mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1137816 - Add a test for interfaces exposed to service workers; r=baku
This commit is contained in:
parent
4c972a5d64
commit
2ff8733a59
6
dom/workers/test/serviceworkers/message_receiver.html
Normal file
6
dom/workers/test/serviceworkers/message_receiver.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
navigator.serviceWorker.onmessage = function(e) {
|
||||
window.parent.postMessage(e.data, "*");
|
||||
};
|
||||
</script>
|
@ -26,6 +26,9 @@ support-files =
|
||||
fetch/fetch_tests.js
|
||||
match_all_properties_worker.js
|
||||
match_all_clients/match_all_controlled.html
|
||||
test_serviceworker_interfaces.js
|
||||
serviceworker_wrapper.js
|
||||
message_receiver.html
|
||||
close_test.js
|
||||
|
||||
[test_unregister.html]
|
||||
@ -45,3 +48,4 @@ skip-if = true # Bug 1133805
|
||||
[test_post_message_advanced.html]
|
||||
[test_match_all_client_properties.html]
|
||||
[test_close.html]
|
||||
[test_serviceworker_interfaces.html]
|
||||
|
131
dom/workers/test/serviceworkers/serviceworker_wrapper.js
Normal file
131
dom/workers/test/serviceworkers/serviceworker_wrapper.js
Normal file
@ -0,0 +1,131 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
//
|
||||
// ServiceWorker equivalent of worker_wrapper.js.
|
||||
|
||||
var client;
|
||||
|
||||
function ok(a, msg) {
|
||||
dump("OK: " + !!a + " => " + a + ": " + msg + "\n");
|
||||
client.postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
dump("IS: " + (a===b) + " => " + a + " | " + b + ": " + msg + "\n");
|
||||
client.postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
|
||||
}
|
||||
|
||||
function workerTestArrayEquals(a, b) {
|
||||
if (!Array.isArray(a) || !Array.isArray(b) || a.length != b.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0, n = a.length; i < n; ++i) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function workerTestDone() {
|
||||
client.postMessage({ type: 'finish' });
|
||||
}
|
||||
|
||||
function workerTestGetPrefs(prefs, cb) {
|
||||
addEventListener('message', function workerTestGetPrefsCB(e) {
|
||||
if (e.data.type != 'returnPrefs' ||
|
||||
!workerTestArrayEquals(prefs, e.data.prefs)) {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetPrefsCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getPrefs',
|
||||
prefs: prefs
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetPermissions(permissions, cb) {
|
||||
addEventListener('message', function workerTestGetPermissionsCB(e) {
|
||||
if (e.data.type != 'returnPermissions' ||
|
||||
!workerTestArrayEquals(permissions, e.data.permissions)) {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetPermissionsCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getPermissions',
|
||||
permissions: permissions
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetVersion(cb) {
|
||||
addEventListener('message', function workerTestGetVersionCB(e) {
|
||||
if (e.data.type !== 'returnVersion') {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetVersionCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getVersion'
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetUserAgent(cb) {
|
||||
addEventListener('message', function workerTestGetUserAgentCB(e) {
|
||||
if (e.data.type !== 'returnUserAgent') {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetUserAgentCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getUserAgent'
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetOSCPU(cb) {
|
||||
addEventListener('message', function workerTestGetOSCPUCB(e) {
|
||||
if (e.data.type !== 'returnOSCPU') {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetOSCPUCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getOSCPU'
|
||||
});
|
||||
}
|
||||
|
||||
function workerTestGetIsB2G(cb) {
|
||||
addEventListener('message', function workerTestGetIsB2GCB(e) {
|
||||
if (e.data.type !== 'returnIsB2G') {
|
||||
return;
|
||||
}
|
||||
removeEventListener('message', workerTestGetIsB2GCB);
|
||||
cb(e.data.result);
|
||||
});
|
||||
client.postMessage({
|
||||
type: 'getIsB2G'
|
||||
});
|
||||
}
|
||||
|
||||
addEventListener('message', function workerWrapperOnMessage(e) {
|
||||
removeEventListener('message', workerWrapperOnMessage);
|
||||
var data = e.data;
|
||||
self.clients.matchAll().then(function(clients) {
|
||||
client = clients[0];
|
||||
try {
|
||||
importScripts(data.script);
|
||||
} catch(e) {
|
||||
client.postMessage({
|
||||
type: 'status',
|
||||
status: false,
|
||||
msg: 'worker failed to import ' + data.script + "; error: " + e.message
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
@ -0,0 +1,113 @@
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Validate Interfaces Exposed to Service Workers</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="../worker_driver.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function setupSW(registration) {
|
||||
var worker = registration.waiting ||
|
||||
registration.active;
|
||||
window.onmessage = function(event) {
|
||||
if (event.data.type == 'finish') {
|
||||
registration.unregister().then(function(success) {
|
||||
ok(success, "The service worker should be unregistered successfully");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
} else if (event.data.type == 'status') {
|
||||
ok(event.data.status, event.data.msg);
|
||||
|
||||
} else if (event.data.type == 'getPrefs') {
|
||||
var result = {};
|
||||
event.data.prefs.forEach(function(pref) {
|
||||
result[pref] = SpecialPowers.Services.prefs.getBoolPref(pref);
|
||||
});
|
||||
worker.postMessage({
|
||||
type: 'returnPrefs',
|
||||
prefs: event.data.prefs,
|
||||
result: result
|
||||
});
|
||||
|
||||
} else if (event.data.type == 'getPermissions') {
|
||||
var result = {};
|
||||
event.data.permissions.forEach(function(permission) {
|
||||
result[permission] = SpecialPowers.hasPermission(permission, window.document);
|
||||
});
|
||||
worker.postMessage({
|
||||
type: 'returnPermissions',
|
||||
permissions: event.data.permissions,
|
||||
result: result
|
||||
});
|
||||
|
||||
} else if (event.data.type == 'getVersion') {
|
||||
var result = SpecialPowers.Cc['@mozilla.org/xre/app-info;1'].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
|
||||
worker.postMessage({
|
||||
type: 'returnVersion',
|
||||
result: result
|
||||
});
|
||||
|
||||
} else if (event.data.type == 'getUserAgent') {
|
||||
worker.postMessage({
|
||||
type: 'returnUserAgent',
|
||||
result: navigator.userAgent
|
||||
});
|
||||
} else if (event.data.type == 'getOSCPU') {
|
||||
worker.postMessage({
|
||||
type: 'returnOSCPU',
|
||||
result: navigator.oscpu
|
||||
});
|
||||
} else if (event.data.type == 'getIsB2G') {
|
||||
worker.postMessage({
|
||||
type: 'returnIsB2G',
|
||||
result: SpecialPowers.isB2G
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
worker.onerror = function(event) {
|
||||
ok(false, 'Worker had an error: ' + event.data);
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = "message_receiver.html";
|
||||
iframe.onload = function() {
|
||||
worker.postMessage({ script: "test_serviceworker_interfaces.js" });
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
navigator.serviceWorker.register("serviceworker_wrapper.js", {scope: "."})
|
||||
.then(function(registration) {
|
||||
if (registration.installing) {
|
||||
registration.installing.onstatechange = function(e) {
|
||||
setupSW(registration);
|
||||
e.target.onstatechange = null;
|
||||
};
|
||||
} else {
|
||||
setupSW(registration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.fetch.enabled", true],
|
||||
["dom.caches.enabled", true]
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
278
dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
Normal file
278
dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
Normal file
@ -0,0 +1,278 @@
|
||||
// This is a list of all interfaces that are exposed to workers.
|
||||
// Please only add things to this list with great care and proper review
|
||||
// from the associated module peers.
|
||||
|
||||
// This file lists global interfaces we want exposed and verifies they
|
||||
// are what we intend. Each entry in the arrays below can either be a
|
||||
// simple string with the interface name, or an object with a 'name'
|
||||
// property giving the interface name as a string, and additional
|
||||
// properties which qualify the exposure of that interface. For example:
|
||||
//
|
||||
// [
|
||||
// "AGlobalInterface",
|
||||
// {name: "ExperimentalThing", release: false},
|
||||
// {name: "OptionalThing", pref: "some.thing.enabled"},
|
||||
// ];
|
||||
//
|
||||
// See createInterfaceMap() below for a complete list of properties.
|
||||
|
||||
// IMPORTANT: Do not change this list without review from
|
||||
// a JavaScript Engine peer!
|
||||
var ecmaGlobals =
|
||||
[
|
||||
"Array",
|
||||
"ArrayBuffer",
|
||||
"Boolean",
|
||||
"DataView",
|
||||
"Date",
|
||||
"Error",
|
||||
"EvalError",
|
||||
"Float32Array",
|
||||
"Float64Array",
|
||||
"Function",
|
||||
"Infinity",
|
||||
"Int16Array",
|
||||
"Int32Array",
|
||||
"Int8Array",
|
||||
"InternalError",
|
||||
{name: "Intl", b2g: false, android: false},
|
||||
"Iterator",
|
||||
"JSON",
|
||||
"Map",
|
||||
"Math",
|
||||
"NaN",
|
||||
"Number",
|
||||
"Object",
|
||||
"Proxy",
|
||||
"RangeError",
|
||||
"ReferenceError",
|
||||
"RegExp",
|
||||
"Set",
|
||||
{name: "SharedArrayBuffer", nightly: true},
|
||||
{name: "SharedInt8Array", nightly: true},
|
||||
{name: "SharedUint8Array", nightly: true},
|
||||
{name: "SharedUint8ClampedArray", nightly: true},
|
||||
{name: "SharedInt16Array", nightly: true},
|
||||
{name: "SharedUint16Array", nightly: true},
|
||||
{name: "SharedInt32Array", nightly: true},
|
||||
{name: "SharedUint32Array", nightly: true},
|
||||
{name: "SharedFloat32Array", nightly: true},
|
||||
{name: "SharedFloat64Array", nightly: true},
|
||||
{name: "SIMD", nightly: true},
|
||||
{name: "Atomics", nightly: true},
|
||||
"StopIteration",
|
||||
"String",
|
||||
"Symbol",
|
||||
"SyntaxError",
|
||||
{name: "TypedObject", nightly: true},
|
||||
"TypeError",
|
||||
"Uint16Array",
|
||||
"Uint32Array",
|
||||
"Uint8Array",
|
||||
"Uint8ClampedArray",
|
||||
"URIError",
|
||||
"WeakMap",
|
||||
"WeakSet",
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from
|
||||
// a JavaScript Engine peer!
|
||||
|
||||
// IMPORTANT: Do not change the list below without review from a DOM peer!
|
||||
var interfaceNamesInGlobalScope =
|
||||
[
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Blob",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "BroadcastChannel", pref: "dom.broadcastChannel.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "Cache", pref: "dom.caches.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "CacheStorage", pref: "dom.caches.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Client",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Clients",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DataStore", b2g: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "DataStoreCursor", b2g: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"DOMError",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"DOMException",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"DOMStringList",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Event",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"EventTarget",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ExtendableEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"FetchEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"File",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"FileReaderSync",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "Headers", pref: "dom.fetch.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBCursor",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBDatabase",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBFactory",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBIndex",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBKeyRange",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBObjectStore",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBOpenDBRequest",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBRequest",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBTransaction",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"IDBVersionChangeEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ImageData",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"InstallEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"MessageEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"MessagePort",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Performance",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Promise",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Request",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Response",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ServiceWorker",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ServiceWorkerGlobalScope",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"TextDecoder",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"TextEncoder",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XMLHttpRequest",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XMLHttpRequestEventTarget",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XMLHttpRequestUpload",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"URL",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"URLSearchParams",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "WebSocket", pref: "dom.workers.websocket.enabled" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WorkerGlobalScope",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WorkerLocation",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WorkerNavigator",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from a DOM peer!
|
||||
|
||||
function createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
var isNightly = version.endsWith("a1");
|
||||
var isRelease = !version.contains("a");
|
||||
var isDesktop = !/Mobile|Tablet/.test(userAgent);
|
||||
var isAndroid = !!navigator.userAgent.contains("Android");
|
||||
|
||||
var interfaceMap = {};
|
||||
|
||||
function addInterfaces(interfaces)
|
||||
{
|
||||
for (var entry of interfaces) {
|
||||
if (typeof(entry) === "string") {
|
||||
interfaceMap[entry] = true;
|
||||
} else if ((entry.nightly === !isNightly) ||
|
||||
(entry.desktop === !isDesktop) ||
|
||||
(entry.android === !isAndroid) ||
|
||||
(entry.b2g === !isB2G) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.pref && !prefMap[entry.pref]) ||
|
||||
(entry.permission && !permissionMap[entry.permission])) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addInterfaces(ecmaGlobals);
|
||||
addInterfaces(interfaceNamesInGlobalScope);
|
||||
|
||||
return interfaceMap;
|
||||
}
|
||||
|
||||
function runTest(prefMap, permissionMap, version, userAgent, isB2G) {
|
||||
var interfaceMap = createInterfaceMap(prefMap, permissionMap, version, userAgent, isB2G);
|
||||
for (var name of Object.getOwnPropertyNames(self)) {
|
||||
// An interface name should start with an upper case character.
|
||||
if (!/^[A-Z]/.test(name)) {
|
||||
continue;
|
||||
}
|
||||
ok(interfaceMap[name],
|
||||
"If this is failing: DANGER, are you sure you want to expose the new interface " + name +
|
||||
" to all webpages as a property on the service worker? Do not make a change to this file without a " +
|
||||
" review from a DOM peer for that specific change!!! (or a JS peer for changes to ecmaGlobals)");
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
for (var name of Object.keys(interfaceMap)) {
|
||||
ok(name in self === interfaceMap[name],
|
||||
name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
|
||||
if (!interfaceMap[name]) {
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
}
|
||||
is(Object.keys(interfaceMap).length, 0,
|
||||
"The following interface(s) are not enumerated: " + Object.keys(interfaceMap).join(", "));
|
||||
}
|
||||
|
||||
function appendPrefs(prefs, interfaces) {
|
||||
for (var entry of interfaces) {
|
||||
if (entry.pref !== undefined && prefs.indexOf(entry.pref) === -1) {
|
||||
prefs.push(entry.pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var prefs = [];
|
||||
appendPrefs(prefs, ecmaGlobals);
|
||||
appendPrefs(prefs, interfaceNamesInGlobalScope);
|
||||
|
||||
function appendPermissions(permissions, interfaces) {
|
||||
for (var entry of interfaces) {
|
||||
if (entry.permission !== undefined &&
|
||||
permissions.indexOf(entry.permission) === -1) {
|
||||
permissions.push(entry.permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var permissions = [];
|
||||
appendPermissions(permissions, ecmaGlobals);
|
||||
appendPermissions(permissions, interfaceNamesInGlobalScope);
|
||||
|
||||
workerTestGetPrefs(prefs, function(prefMap) {
|
||||
workerTestGetPermissions(permissions, function(permissionMap) {
|
||||
workerTestGetVersion(function(version) {
|
||||
workerTestGetUserAgent(function(userAgent) {
|
||||
workerTestGetIsB2G(function(isB2G) {
|
||||
runTest(prefMap, permissionMap, version, userAgent, isB2G);
|
||||
workerTestDone();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user