summaryrefslogtreecommitdiffstats
path: root/dom/workers/test/serviceworkers/fetch/context/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/workers/test/serviceworkers/fetch/context/index.html')
-rw-r--r--dom/workers/test/serviceworkers/fetch/context/index.html422
1 files changed, 422 insertions, 0 deletions
diff --git a/dom/workers/test/serviceworkers/fetch/context/index.html b/dom/workers/test/serviceworkers/fetch/context/index.html
new file mode 100644
index 000000000..c6dfef99c
--- /dev/null
+++ b/dom/workers/test/serviceworkers/fetch/context/index.html
@@ -0,0 +1,422 @@
+<!DOCTYPE html>
+<script>
+ var isAndroid = navigator.userAgent.includes("Android");
+ var isB2G = !isAndroid && /Mobile|Tablet/.test(navigator.userAgent);
+
+ function ok(v, msg) {
+ window.parent.postMessage({status: "ok", result: !!v, message: msg}, "*");
+ }
+
+ function is(a, b, msg) {
+ ok(a === b, msg + ", expected '" + b + "', got '" + a + "'");
+ }
+
+ function todo(v, msg) {
+ window.parent.postMessage({status: "todo", result: !!v, message: msg}, "*");
+ }
+
+ function finish() {
+ window.parent.postMessage({status: "done"}, "*");
+ }
+
+ function testFetch() {
+ return fetch("fetch.txt").then(function(r) {
+ return r.text();
+ }).then(function(body) {
+ is(body, "so fetch", "A fetch() Request should have the 'fetch' context");
+ });
+ }
+
+ function testImage() {
+ return new Promise(function(resolve, reject) {
+ var img = document.createElement("img");
+ img.src = "img.jpg";
+ // The service worker will respond with an existing image only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ img.onload = resolve;
+ img.onerror = reject;
+ });
+ }
+
+ function testImageSrcSet() {
+ return new Promise(function(resolve, reject) {
+ var img = document.createElement("img");
+ img.srcset = "responsive.jpg 100w";
+ // The service worker will respond with an existing image only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ img.onload = resolve;
+ img.onerror = reject;
+ });
+ }
+
+ function testPicture() {
+ return new Promise(function(resolve, reject) {
+ var pic = document.createElement("picture");
+ var img = document.createElement("img");
+ pic.appendChild(img);
+ img.src = "responsive.jpg?picture";
+ // The service worker will respond with an existing image only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ img.onload = resolve;
+ img.onerror = reject;
+ });
+ }
+
+ function testAudio() {
+ return new Promise(function(resolve, reject) {
+ var audio = document.createElement("audio");
+ audio.src = "audio.ogg";
+ audio.preload = "metadata";
+ // The service worker will respond with an existing audio only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ audio.onloadedmetadata = resolve;
+ audio.onerror = reject;
+ });
+ }
+
+ function testVideo() {
+ return new Promise(function(resolve, reject) {
+ var video = document.createElement("video");
+ video.src = "video.ogg";
+ video.preload = "metadata";
+ // The service worker will respond with an existing video only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ video.onloadedmetadata = resolve;
+ video.onerror = reject;
+ });
+ }
+
+ function testBeacon() {
+ ok(navigator.sendBeacon("beacon.sjs"), "Sending the beacon should succeed");
+ // query the context from beacon.sjs
+ return fetch("beacon.sjs?queryContext")
+ .then(function(r) {
+ return r.text();
+ }).then(function(body) {
+ is(body, "beacon", "The context for the intercepted beacon should be correct");
+ });
+ }
+
+ function testCSPReport() {
+ return new Promise(function(resolve, reject) {
+ var iframe = document.createElement("iframe");
+ iframe.src = "csp-violate.sjs";
+ document.documentElement.appendChild(iframe);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "csp-report") {
+ is(e.data.context, "cspreport", "Expected the cspreport context on a CSP violation report");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testEmbed() {
+ return Promise.resolve().then(function() {
+ todo(false, "<embed> tag is not currently intercepted. See Bug 1168676.");
+ });
+
+ return new Promise(function(resolve, reject) {
+ var embed = document.createElement("embed");
+ embed.src = "embed";
+ document.documentElement.appendChild(embed);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "embed") {
+ is(e.data.context, "embed", "Expected the object context on an embed");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testObject() {
+ return Promise.resolve().then(function() {
+ todo(false, "<object> tag is not currently intercepted. See Bug 1168676");
+ });
+
+ return new Promise(function(resolve, reject) {
+ var object = document.createElement("object");
+ object.data = "object";
+ document.documentElement.appendChild(object);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "object") {
+ is(e.data.context, "object", "Expected the object context on an object");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testFont() {
+ return new Promise(function(resolve, reject) {
+ var css = '@font-face { font-family: "sw-font"; src: url("font"); }';
+ css += '* { font-family: "sw-font"; }';
+ var style = document.createElement("style");
+ style.appendChild(document.createTextNode(css));
+ document.documentElement.appendChild(style);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "font") {
+ is(e.data.context, "font", "Expected the font context on an font");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testIFrame() {
+ return new Promise(function(resolve, reject) {
+ var iframe = document.createElement("iframe");
+ iframe.src = "iframe";
+ document.documentElement.appendChild(iframe);
+ // The service worker will respond with an existing document only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ iframe.onload = resolve;
+ iframe.onerror = reject;
+ });
+ }
+
+ function testFrame() {
+ return new Promise(function(resolve, reject) {
+ var frame = document.createElement("frame");
+ frame.src = "frame";
+ document.documentElement.appendChild(frame);
+ // The service worker will respond with an existing document only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ frame.onload = resolve;
+ frame.onerror = reject;
+ });
+ }
+
+ function testInternal() {
+ if (isB2G) {
+ // We can't open new windows on b2g, so skip this part of the test there.
+ return Promise.resolve();
+ }
+ return new Promise(function(resolve, reject) {
+ // Test this with a new window opened through script. There are of course
+ // other possible ways of testing this too.
+ var win = window.open("newwindow", "_blank", "width=100,height=100");
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "newwindow") {
+ is(e.data.context, "internal", "Expected the internal context on a newly opened window");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ win.close();
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testPing() {
+ return new Promise(function(resolve, reject) {
+ var iframe = document.createElement("iframe");
+ iframe.src = "ping.html";
+ document.documentElement.appendChild(iframe);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "ping") {
+ is(e.data.context, "ping", "Expected the ping context on an anchor ping");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testPlugin() {
+ return Promise.resolve().then(function() {
+ todo(false, "plugins are not currently intercepted. See Bug 1168676.");
+ });
+
+ var isMobile = /Mobile|Tablet/.test(navigator.userAgent);
+ if (isMobile || parent.isMulet()) {
+ // We can't use plugins on mobile, so skip this part of the test there.
+ return Promise.resolve();
+ }
+
+ return new Promise(function(resolve, reject) {
+ var embed = document.createElement("embed");
+ embed.type = "application/x-test";
+ embed.setAttribute("posturl", "plugin");
+ embed.setAttribute("postmode", "stream");
+ embed.setAttribute("streammode", "normal");
+ embed.setAttribute("src", "fetch.txt");
+ document.documentElement.appendChild(embed);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "plugin") {
+ is(e.data.context, "plugin", "Expected the plugin context on a request coming from a plugin");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ // Without this, the test leaks in e10s!
+ embed.parentNode.removeChild(embed);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testScript() {
+ return new Promise(function(resolve, reject) {
+ var script = document.createElement("script");
+ script.src = "script.js";
+ document.documentElement.appendChild(script);
+ // The service worker will respond with an existing script only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ script.onload = resolve;
+ script.onerror = reject;
+ });
+ }
+
+ function testStyle() {
+ return new Promise(function(resolve, reject) {
+ var link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.href = "style.css";
+ document.documentElement.appendChild(link);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "style") {
+ is(e.data.context, "style", "Expected the style context on a request coming from a stylesheet");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testTrack() {
+ return new Promise(function(resolve, reject) {
+ var video = document.createElement("video");
+ var track = document.createElement("track");
+ track.src = "track";
+ video.appendChild(track);
+ document.documentElement.appendChild(video);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "track") {
+ is(e.data.context, "track", "Expected the track context on a request coming from a track");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testXHR() {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("get", "xhr", true);
+ xhr.send();
+ // The service worker will respond with an existing resource only if the
+ // Request has the correct context, otherwise the Promise will get
+ // rejected and the test will fail.
+ xhr.onload = resolve;
+ xhr.onerror = reject;
+ });
+ }
+
+ function testXSLT() {
+ return new Promise(function(resolve, reject) {
+ var iframe = document.createElement("iframe");
+ iframe.src = "xml.xml";
+ document.documentElement.appendChild(iframe);
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "xslt") {
+ is(e.data.context, "xslt", "Expected the xslt context on an XSLT stylesheet");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ // Without this, the test leaks in e10s!
+ iframe.parentNode.removeChild(iframe);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ function testWorker() {
+ return new Promise(function(resolve, reject) {
+ var worker = new Worker("myworker");
+ worker.onmessage = function(e) {
+ if (e.data == "ack") {
+ worker.terminate();
+ resolve();
+ }
+ };
+ worker.onerror = reject;
+ });
+ }
+
+ function testNestedWorker() {
+ return new Promise(function(resolve, reject) {
+ var worker = new Worker("myparentworker");
+ worker.onmessage = function(e) {
+ if (e.data == "ack") {
+ worker.terminate();
+ resolve();
+ }
+ };
+ worker.onerror = reject;
+ });
+ }
+
+ function testSharedWorker() {
+ return new Promise(function(resolve, reject) {
+ var worker = new SharedWorker("mysharedworker");
+ worker.port.start();
+ worker.port.onmessage = function(e) {
+ if (e.data == "ack") {
+ resolve();
+ }
+ };
+ worker.onerror = reject;
+ });
+ }
+
+ function testNestedWorkerInSharedWorker() {
+ return new Promise(function(resolve, reject) {
+ var worker = new SharedWorker("myparentsharedworker");
+ worker.port.start();
+ worker.port.onmessage = function(e) {
+ if (e.data == "ack") {
+ resolve();
+ }
+ };
+ worker.onerror = reject;
+ });
+ }
+
+ function testCache() {
+ return new Promise(function(resolve, reject) {
+ // Issue an XHR that will be intercepted by the SW in order to start off
+ // the test with a RequestContext value that is not the default ("fetch").
+ // This needs to run inside a fetch event handler because synthesized
+ // RequestContext objects can only have the "fetch" context, and we'd
+ // prefer to test the more general case of some other RequestContext value.
+ var xhr = new XMLHttpRequest();
+ xhr.open("get", "cache", true);
+ xhr.send();
+ navigator.serviceWorker.addEventListener("message", function onMessage(e) {
+ if (e.data.data == "cache") {
+ ok(e.data.success, "The RequestContext can be persisted in the cache.");
+ navigator.serviceWorker.removeEventListener("message", onMessage);
+ resolve();
+ }
+ }, false);
+ });
+ }
+
+ var testName = location.search.substr(1);
+ window[testName]().then(function() {
+ finish();
+ }, function(e) {
+ ok(false, "A promise was rejected: " + e);
+ finish();
+ });
+</script>