Bug 1159378 - Part 3: Refactor the logic of test_periodic_update.html into a helper script; r=nsm

This helper script will allow us to run the same test across both HTTP
and HTTPS origins.  This patch also uses postMessage instead of a direct
function call on the parent window, because in the HTTPS case, that
window will be cross-origin.  It also moves the code to trigger the
update and get the corresponding updatefound event to
wait_for_update.html, since getting the service worker registration
cross-origin is not possible.
This commit is contained in:
Ehsan Akhgari 2015-05-04 10:18:12 -04:00
parent 75d02038c7
commit 06cf844bd9
8 changed files with 106 additions and 85 deletions

View File

@ -72,9 +72,11 @@ support-files =
worker_updatefoundevent2.js
updatefoundevent.html
empty.js
periodic_update_test.js
periodic.sjs
periodic/frame.html
periodic/register.html
periodic/wait_for_update.html
periodic/unregister.html
[test_unregister.html]

View File

@ -1,22 +1,24 @@
function handleRequest(request, response) {
var stateName = request.scheme + 'periodiccounter';
if (request.queryString == 'clearcounter') {
setState('periodiccounter', '');
setState(stateName, '');
return;
}
if (!getState('periodiccounter')) {
setState('periodiccounter', '1');
if (!getState(stateName)) {
setState(stateName, '1');
} else {
// Make sure that we pass a string value to setState!
setState('periodiccounter', "" + (parseInt(getState('periodiccounter')) + 1));
setState(stateName, "" + (parseInt(getState(stateName)) + 1));
}
response.setHeader("Content-Type", "application/javascript", false);
response.write(getScript());
response.write(getScript(stateName));
}
function getScript() {
function getScript(stateName) {
return "onfetch = function(e) {" +
"if (e.request.url.indexOf('get-sw-version') > -1) {" +
"e.respondWith(new Response('" + getState('periodiccounter') + "'));" +
"e.respondWith(new Response('" + getState(stateName) + "'));" +
"}" +
"};";
}

View File

@ -3,6 +3,6 @@
fetch("get-sw-version").then(function(r) {
return r.text();
}).then(function(body) {
parent.callback(body);
parent.postMessage({status: "callback", data: body}, "*");
});
</script>

View File

@ -1,7 +1,7 @@
<!DOCTYPE html>
<script>
function done() {
parent.callback();
parent.postMessage({status: "callback", data: "done"}, "*");
}
navigator.serviceWorker.ready.then(done);

View File

@ -5,7 +5,7 @@
}).then(function(registration) {
registration.unregister().then(function(success) {
if (success) {
parent.callback();
parent.postMessage({status: "callback", data: "done"}, "*");
} else {
dump("Unregister failed\n");
}

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<script>
navigator.serviceWorker.getRegistration(".").then(function(reg) {
reg.onupdatefound = function() {
reg.onupdatefound = null;
var sw = reg.installing;
sw.onstatechange = function() {
sw.onstatechange = null;
var success = !reg.waiting && reg.active;
parent.postMessage({status: "callback", data: "done"}, "*");
};
};
SpecialPowers.startPeriodicServiceWorkerUpdates();
});
</script>

View File

@ -0,0 +1,74 @@
var oldSWVersion, newSWVersion;
// This will be set by the test to the base directory for the test files.
var gPrefix;
function start() {
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
function testVersion() {
// Verify that the service worker has been correctly updated.
testFrame(gPrefix + "periodic/frame.html").then(function(body) {
newSWVersion = parseInt(body);
is(newSWVersion, 2, "Expected correct new version");
ok(newSWVersion > oldSWVersion,
"The SW should be successfully updated, old: " + oldSWVersion +
", new: " + newSWVersion);
unregisterSW().then(function() {
SimpleTest.finish();
});
});
}
registerSW().then(function() {
return testFrame(gPrefix + "periodic/frame.html").then(function(body) {
oldSWVersion = parseInt(body);
is(oldSWVersion, 1, "Expected correct old version");
});
}).then(function() {
return testFrame(gPrefix + "periodic/wait_for_update.html");
}).then(function() {
return testVersion();
});
}
function testFrame(src) {
return new Promise(function(resolve, reject) {
var iframe = document.createElement("iframe");
iframe.src = src;
window.onmessage = function(e) {
if (e.data.status == "callback") {
window.onmessage = null;
var result = e.data.data;
iframe.src = "about:blank";
document.body.removeChild(iframe);
iframe = null;
SpecialPowers.exactGC(window, function() {
resolve(result);
});
}
};
document.body.appendChild(iframe);
});
}
function registerSW() {
return testFrame(gPrefix + "periodic/register.html");
}
function unregisterSW() {
return testFrame(gPrefix + "periodic/unregister.html");
}
function runTheTest() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["dom.serviceWorkers.periodic-updates.enabled", true],
]}, function() {
start();
});
}

View File

@ -7,6 +7,7 @@
<head>
<title>Bug 1112469 - Test the periodic update of service workers</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="periodic_update_test.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
@ -15,82 +16,9 @@
<pre id="test"></pre>
<script class="testbody" type="text/javascript">
var oldSWVersion, newSWVersion;
gPrefix = "http://mochi.test:8888/tests/dom/workers/test/serviceworkers/";
runTheTest();
function start() {
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
function testVersion(sw) {
// Verify that the service worker has been correctly updated.
testFrame("periodic/frame.html").then(function(body) {
newSWVersion = parseInt(body);
is(newSWVersion, 2, "Expected correct new version");
ok(newSWVersion > oldSWVersion,
"The SW should be successfully updated, old: " + oldSWVersion +
", new: " + newSWVersion);
unregisterSW().then(function() {
SimpleTest.finish();
});
});
}
registerSW().then(function() {
return testFrame("periodic/frame.html").then(function(body) {
oldSWVersion = parseInt(body);
is(oldSWVersion, 1, "Expected correct old version");
});
}).then(function() {
return navigator.serviceWorker.getRegistration("periodic/foo");
}).then(function(reg) {
reg.onupdatefound = function() {
reg.onupdatefound = null;
var sw = reg.installing;
sw.onstatechange = function() {
sw.onstatechange = null;
ok(!reg.waiting && reg.active, "New worker must get activated immediately");
testVersion(reg.active);
};
};
}).then(function() {
SpecialPowers.startPeriodicServiceWorkerUpdates();
});
}
function testFrame(src) {
return new Promise(function(resolve, reject) {
var iframe = document.createElement("iframe");
iframe.src = src;
window.callback = function(result) {
iframe.src = "about:blank";
document.body.removeChild(iframe);
iframe = null;
SpecialPowers.exactGC(window, function() {
resolve(result);
});
};
document.body.appendChild(iframe);
});
}
function registerSW() {
return testFrame("periodic/register.html");
}
function unregisterSW() {
return testFrame("periodic/unregister.html");
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["dom.serviceWorkers.periodic-updates.enabled", true],
]}, function() {
start();
});
</script>
</pre>
</body>