Bug 1146194: Multiple cookies with the same name not shown

Issue #31
This commit is contained in:
janekptacijarabaci 2018-03-02 13:36:16 +01:00 committed by Roy Tam
commit a5b4f6e003
27 changed files with 829 additions and 169 deletions

View file

@ -11,6 +11,7 @@ support-files =
doc_perf.html
navigate-first.html
navigate-second.html
storage-cookies-same-name.html
storage-dynamic-windows.html
storage-listings.html
storage-unsecured-iframe.html
@ -80,6 +81,7 @@ skip-if = e10s # Bug 1183605 - devtools/server/tests/browser/ tests are still di
#[browser_perf-front-profiler-01.js] bug 1077464
#[browser_perf-front-profiler-05.js] bug 1077464
#[browser_perf-front-profiler-06.js]
[browser_storage_cookies-duplicate-names.js]
[browser_storage_dynamic_windows.js]
[browser_storage_listings.js]
[browser_storage_updates.js]

View file

@ -0,0 +1,105 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the storage panel is able to display multiple cookies with the same
// name (and different paths).
const {StorageFront} = require("devtools/shared/fronts/storage");
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/server/tests/browser/storage-helpers.js", this);
const TESTDATA = {
"test1.example.org": [
{
name: "name",
value: "value1",
expires: 0,
path: "/",
host: "test1.example.org",
isDomain: false,
isSecure: false,
},
{
name: "name",
value: "value2",
expires: 0,
path: "/path2/",
host: "test1.example.org",
isDomain: false,
isSecure: false,
},
{
name: "name",
value: "value3",
expires: 0,
path: "/path3/",
host: "test1.example.org",
isDomain: false,
isSecure: false,
}
]
};
add_task(function* () {
yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-cookies-same-name.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
let form = yield connectDebuggerClient(client);
let front = StorageFront(client, form);
let data = yield front.listStores();
ok(data.cookies, "Cookies storage actor is present");
yield testCookies(data.cookies);
yield clearStorage();
// Forcing GC/CC to get rid of docshells and windows created by this test.
forceCollections();
yield client.close();
forceCollections();
DebuggerServer.destroy();
forceCollections();
});
function testCookies(cookiesActor) {
let numHosts = Object.keys(cookiesActor.hosts).length;
is(numHosts, 1, "Correct number of host entries for cookies");
return testCookiesObjects(0, cookiesActor.hosts, cookiesActor);
}
var testCookiesObjects = Task.async(function* (index, hosts, cookiesActor) {
let host = Object.keys(hosts)[index];
let matchItems = data => {
is(data.total, TESTDATA[host].length,
"Number of cookies in host " + host + " matches");
for (let item of data.data) {
let found = false;
for (let toMatch of TESTDATA[host]) {
if (item.name === toMatch.name &&
item.host === toMatch.host &&
item.path === toMatch.path) {
found = true;
ok(true, "Found cookie " + item.name + " in response");
is(item.value.str, toMatch.value, "The value matches.");
is(item.expires, toMatch.expires, "The expiry time matches.");
is(item.path, toMatch.path, "The path matches.");
is(item.host, toMatch.host, "The host matches.");
is(item.isSecure, toMatch.isSecure, "The isSecure value matches.");
is(item.isDomain, toMatch.isDomain, "The isDomain value matches.");
break;
}
}
ok(found, "cookie " + item.name + " should exist in response");
}
};
ok(!!TESTDATA[host], "Host is present in the list : " + host);
matchItems(yield cookiesActor.getStoreObjects(host));
if (index == Object.keys(hosts).length - 1) {
return;
}
yield testCookiesObjects(++index, hosts, cookiesActor);
});

View file

@ -66,6 +66,7 @@ function markOutMatched(toBeEmptied, data, deleted) {
info("Testing for " + storageType);
for (let host in data[storageType]) {
ok(toBeEmptied[storageType][host], "Host " + host + " found");
if (!deleted) {
for (let item of data[storageType][host]) {
let index = toBeEmptied[storageType][host].indexOf(item);
@ -87,50 +88,6 @@ function markOutMatched(toBeEmptied, data, deleted) {
}
}
// function testReload(front) {
// info("Testing if reload works properly");
// let shouldBeEmptyFirst = Cu.cloneInto(beforeReload, {});
// let shouldBeEmptyLast = Cu.cloneInto(beforeReload, {});
// return new Promise(resolve => {
// let onStoresUpdate = data => {
// info("in stores update of testReload");
// // This might be second time stores update is happening, in which case,
// // data.deleted will be null.
// // OR.. This might be the first time on a super slow machine where both
// // data.deleted and data.added is missing in the first update.
// if (data.deleted) {
// markOutMatched(shouldBeEmptyFirst, data.deleted, true);
// }
// if (!Object.keys(shouldBeEmptyFirst).length) {
// info("shouldBeEmptyFirst is empty now");
// }
// // stores-update call might not have data.added for the first time on
// // slow machines, in which case, data.added will be null
// if (data.added) {
// markOutMatched(shouldBeEmptyLast, data.added);
// }
// if (!Object.keys(shouldBeEmptyLast).length) {
// info("Everything to be received is received.");
// endTestReloaded();
// }
// };
// let endTestReloaded = () => {
// front.off("stores-update", onStoresUpdate);
// resolve();
// };
// front.on("stores-update", onStoresUpdate);
// content.location.reload();
// });
// }
function testAddIframe(front) {
info("Testing if new iframe addition works properly");
return new Promise(resolve => {
@ -142,7 +99,10 @@ function testAddIframe(front) {
"https://sectest1.example.org": ["iframe-s-ss1"]
},
cookies: {
"sectest1.example.org": ["sc1"]
"sectest1.example.org": [
getCookieId("sc1", "sectest1.example.org",
"/browser/devtools/server/tests/browser/")
]
},
indexedDB: {
// empty because indexed db creation happens after the page load, so at
@ -150,7 +110,7 @@ function testAddIframe(front) {
"https://sectest1.example.org": []
},
Cache: {
"https://sectest1.example.org":[]
"https://sectest1.example.org": []
}
};

View file

@ -19,15 +19,6 @@ const storeMap = {
isDomain: false,
isSecure: false,
},
{
name: "cs2",
value: "sessionCookie",
path: "/",
host: ".example.org",
expires: 0,
isDomain: true,
isSecure: false,
},
{
name: "c3",
value: "foobar-2",
@ -337,7 +328,8 @@ function* testStores(data) {
}
function testCookies(cookiesActor) {
is(Object.keys(cookiesActor.hosts).length, 2, "Correct number of host entries for cookies");
is(Object.keys(cookiesActor.hosts).length, 2,
"Correct number of host entries for cookies");
return testCookiesObjects(0, cookiesActor.hosts, cookiesActor);
}
@ -346,9 +338,9 @@ var testCookiesObjects = Task.async(function* (index, hosts, cookiesActor) {
let matchItems = data => {
let cookiesLength = 0;
for (let secureCookie of storeMap.cookies[host]) {
if (secureCookie.isSecure) {
++cookiesLength;
}
if (secureCookie.isSecure) {
++cookiesLength;
}
}
// Any secure cookies did not get stored in the database.
is(data.total, storeMap.cookies[host].length - cookiesLength,

View file

@ -27,7 +27,12 @@ const TESTS = [
expected: {
added: {
cookies: {
"test1.example.org": ["c1", "c2"]
"test1.example.org": [
getCookieId("c1", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
getCookieId("c2", "test1.example.org",
"/browser/devtools/server/tests/browser/")
]
},
localStorage: {
"http://test1.example.org": ["l1"]
@ -48,7 +53,10 @@ const TESTS = [
expected: {
changed: {
cookies: {
"test1.example.org": ["c1"]
"test1.example.org": [
getCookieId("c1", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
}
},
added: {
@ -74,7 +82,10 @@ const TESTS = [
expected: {
deleted: {
cookies: {
"test1.example.org": ["c2"]
"test1.example.org": [
getCookieId("c2", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
},
localStorage: {
"http://test1.example.org": ["l1"]
@ -112,7 +123,10 @@ const TESTS = [
expected: {
added: {
cookies: {
"test1.example.org": ["c3"]
"test1.example.org": [
getCookieId("c3", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
},
sessionStorage: {
"http://test1.example.org": ["s1", "s2"]
@ -125,7 +139,10 @@ const TESTS = [
},
deleted: {
cookies: {
"test1.example.org": ["c1"]
"test1.example.org": [
getCookieId("c1", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
},
localStorage: {
"http://test1.example.org": ["l2"]
@ -158,7 +175,10 @@ const TESTS = [
expected: {
deleted: {
cookies: {
"test1.example.org": ["c3"]
"test1.example.org": [
getCookieId("c3", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
}
}
}

View file

@ -2,6 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/* eslint no-unused-vars: [2, {"vars": "local"}] */
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
@ -19,6 +23,11 @@ const MAIN_DOMAIN = "http://test1.example.org/" + PATH;
const ALT_DOMAIN = "http://sectest1.example.org/" + PATH;
const ALT_DOMAIN_SECURED = "https://sectest1.example.org:443/" + PATH;
// GUID to be used as a separator in compound keys. This must match the same
// constant in devtools/server/actors/storage.js,
// devtools/client/storage/ui.js and devtools/client/storage/test/head.js
const SEPARATOR_GUID = "{9d414cc5-8319-0a04-0586-c0a6ae01670a}";
// All tests are asynchronous.
waitForExplicitFinish();
@ -94,7 +103,6 @@ function once(target, eventName, useCapture = false) {
info("Waiting for event: '" + eventName + "' on " + target + ".");
return new Promise(resolve => {
for (let [add, remove] of [
["addEventListener", "removeEventListener"],
["addListener", "removeListener"],
@ -137,6 +145,8 @@ function getMockTabActor(win) {
}
registerCleanupFunction(function tearDown() {
Services.cookies.removeAll();
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
@ -148,8 +158,11 @@ function idleWait(time) {
function busyWait(time) {
let start = Date.now();
// eslint-disable-next-line
let stack;
while (Date.now() - start < time) { stack = Components.stack; }
while (Date.now() - start < time) {
stack = Components.stack;
}
}
/**
@ -172,11 +185,12 @@ function waitUntil(predicate, interval = 10) {
}
function waitForMarkerType(front, types, predicate,
unpackFun = (name, data) => data.markers,
eventName = "timeline-data")
{
unpackFun = (name, data) => data.markers,
eventName = "timeline-data") {
types = [].concat(types);
predicate = predicate || function () { return true; };
predicate = predicate || function () {
return true;
};
let filteredMarkers = [];
let { promise, resolve } = defer();
@ -190,9 +204,11 @@ function waitForMarkerType(front, types, predicate,
let markers = unpackFun(name, data);
info("Got markers: " + JSON.stringify(markers, null, 2));
filteredMarkers = filteredMarkers.concat(markers.filter(m => types.indexOf(m.name) !== -1));
filteredMarkers = filteredMarkers.concat(
markers.filter(m => types.indexOf(m.name) !== -1));
if (types.every(t => filteredMarkers.some(m => m.name === t)) && predicate(filteredMarkers)) {
if (types.every(t => filteredMarkers.some(m => m.name === t)) &&
predicate(filteredMarkers)) {
front.off(eventName, handler);
resolve(filteredMarkers);
}
@ -201,3 +217,7 @@ function waitForMarkerType(front, types, predicate,
return promise;
}
function getCookieId(name, domain, path) {
return `${name}${SEPARATOR_GUID}${domain}${SEPARATOR_GUID}${path}`;
}

View file

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Storage inspector cookies with duplicate names</title>
</head>
<body onload="createCookies()">
<script type="application/javascript;version=1.7">
"use strict";
function createCookies() {
document.cookie = "name=value1;path=/;";
document.cookie = "name=value2;path=/path2/;";
document.cookie = "name=value3;path=/path3/;";
}
window.removeCookie = function (name) {
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
};
window.clearCookies = function () {
let cookies = document.cookie;
for (let cookie of cookies.split(";")) {
removeCookie(cookie.split("=")[0]);
}
};
</script>
</body>
</html>