Update web-platform-tests to revision 0ed072539aa45d3a5a67c9164b243d27873f257c

This commit is contained in:
WPT Sync Bot 2019-12-13 08:23:34 +00:00
parent 0954871992
commit e613cfd108
76 changed files with 1109 additions and 703 deletions

View file

@ -7,7 +7,7 @@
expected: FAIL
[Opening a blob URL in a new window immediately before revoking it works.]
expected: TIMEOUT
expected: FAIL
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
expected: FAIL

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
[width-047.xht]
expected: FAIL

View file

@ -2,3 +2,6 @@
[listeners are called in order they were added, ignoring capture parameter]
expected: FAIL
[capturing event listener fires before non-capturing listener at target]
expected: FAIL

View file

@ -1,4 +1,4 @@
[remove-and-adopt-crash.html]
[remove-and-adopt-thcrash.html]
[Check that removing a node and then adopting its parent into a different window/document doesn't crash.]
expected: FAIL

View file

@ -1,5 +0,0 @@
[response-trailer.html]
type: testharness
[trailer() test]
expected: FAIL

View file

@ -309,12 +309,6 @@
[<iframe>: separate response Content-Type: */* text/html]
expected: FAIL
[<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL
@ -327,6 +321,9 @@
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
[<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL

View file

@ -11,6 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%0C]
expected: FAIL
[X-Content-Type-Options%3A%20'NosniFF']
[X-Content-Type-Options%3A%20%2Cnosniff]
expected: FAIL

View file

@ -11,7 +11,7 @@
expected: TIMEOUT
[Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.]
expected: FAIL
expected: TIMEOUT
[Embedded credentials matching the top-level are not treated as network errors for same-origin URLs.]
expected: TIMEOUT

View file

@ -1,4 +0,0 @@
[window-serviceworker-success.https.html]
[Test ServiceWorkerContainer.onmessageerror using SharedArrayBuffer]
expected: FAIL

View file

@ -1,5 +1,4 @@
[supported-elements.html]
expected: TIMEOUT
[Contenteditable element should support autofocus]
expected: FAIL
@ -10,7 +9,7 @@
expected: FAIL
[Area element should support autofocus]
expected: TIMEOUT
expected: FAIL
[Host element with delegatesFocus should support autofocus]
expected: FAIL

View file

@ -1,5 +1,5 @@
[form-double-submit-3.html]
expected: ERROR
[<button> should have the same double-submit protection as <input type=submit>]
expected: TIMEOUT
expected: FAIL

View file

@ -1,4 +0,0 @@
[window-serviceworker-success.https.html]
[Test ServiceWorkerContainer.onmessageerror using WebAssembly.Module]
expected: FAIL

View file

@ -3,5 +3,5 @@
expected: FAIL
[test_element_in_collection]
expected:
if os == "mac": FAIL
expected: FAIL

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -1,5 +0,0 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -321,13 +321,12 @@ jobs:
parallel: 5 # chosen to make runtime ~2h
timeoutInMinutes: 180
pool:
vmImage: 'macOS-10.13'
vmImage: 'macOS-10.14'
steps:
- template: tools/ci/azure/checkout.yml
- template: tools/ci/azure/pip_install.yml
parameters:
packages: virtualenv
- template: tools/ci/azure/install_fonts.yml
- template: tools/ci/azure/install_certs.yml
- template: tools/ci/azure/install_safari.yml
parameters:

View file

@ -144,6 +144,10 @@ promise_test(async t => {
assert_equals(calls, 2, "dispatchEvent");
}, "removeListener doesn't remove listener added with addEventListener (capture)");
// See:
// * https://github.com/whatwg/dom/issues/746
// * https://bugzilla.mozilla.org/show_bug.cgi?id=1492446
// * https://bugs.chromium.org/p/chromium/issues/detail?id=949432
promise_test(async t => {
const mql = await createMQL(t);
@ -164,5 +168,5 @@ promise_test(async t => {
calls = [];
mql.dispatchEvent(new Event("change"));
assert_array_equals(calls, ["addEventListener", "addListener"], "dispatchEvent");
}, "listeners are called in order they were added, ignoring capture parameter");
}, "capturing event listener fires before non-capturing listener at target");
</script>

View file

@ -0,0 +1,22 @@
# crashtest tests
Crash tests are used to ensure that a document can be loaded without
crashing or experiencing other low-level issues that may be checked by
implementation-specific tooling (e.g. leaks, asserts, or sanitizer
failures).
Crashtests are identified by the string `-crash` in the filename, or
by being in a directory called `crashtests`.
The simplest crashtest is a single HTML file with any content. The
test passes if the load event is reached, and the browser finishes
painting, without terminating.
In some cases crashtests may need to perform work after the initial
page load. In this case the test may specify a `class=wait` attribute
on the root element. The test will not complete until that attribute
is removed from the root. At the time when the test would otherwise
have ended a `TestRendered` event is emitted; test authors can use
this event to perform modifications that are guaranteed not to be
batched with the initial paint. This matches the behaviour of
[reftests](reftests).

View file

@ -15,6 +15,7 @@ There's also a load of [general guidelines](general-guidelines) that apply to al
general-guidelines
ahem
assumptions
crashtest
css-metadata
css-user-styles
file-names
@ -63,6 +64,11 @@ expectations:
testing everything else. They are built with the testharness.js unit testing
framework, and consist of assertions written in JavaScript.
* [Crashtests](crashtest) tests are used to check that the browser is
able to load a given document without crashing or experiencing other
low-level issues (asserts, leaks, etc.). They pass if the load
completes without error.
* [wdspec](wdspec) tests are written in Python using
[pytest](https://docs.pytest.org/en/latest/) and test [the WebDriver browser
automation protocol](https://w3c.github.io/webdriver/)

View file

@ -278,6 +278,12 @@
input1.removeAttribute("aria-labelledby");
assert_equals(input1.ariaLabelledByElements, null);
input1.setAttribute("aria-labelledby", "nameElement addressElement");
assert_array_equals(input1.ariaLabelledByElements, [nameElement, addressElement]);
input1.ariaLabelledByElements = null;
assert_false(input1.hasAttribute("aria-labelledby", "Nullifying the IDL attribute should remove the content attribute."));
}, "aria-labelledby.");
</script>
@ -305,6 +311,12 @@
link2.removeAttribute("aria-controls");
assert_equals(link2.ariaControlsElements, null);
link2.ariaControlsElements = [panel1, panel2];
assert_equals(link2.getAttribute("aria-controls"), "panel1 panel2");
link2.ariaControlsElements = null;
assert_false(link2.hasAttribute("aria-controls", "Nullifying the IDL attribute should remove the content attribute."));
}, "aria-controls.");
</script>
@ -327,6 +339,12 @@
describedLink.removeAttribute("aria-describedby");
assert_equals(describedLink.ariaDescribedByElements, null);
describedLink.ariaDescribedByElements = [description1, description2];
assert_equals(describedLink.getAttribute("aria-describedby"), "description1 description2");
describedLink.ariaDescribedByElements = null;
assert_false(describedLink.hasAttribute("aria-describedby", "Nullifying the IDL attribute should remove the content attribute."));
}, "aria-describedby.");
</script>
@ -353,6 +371,12 @@
titleHeading.removeAttribute("aria-flowto");
assert_equals(titleHeading.ariaFlowToElements, null);
titleHeading.ariaFlowToElements = [article1, article2];
assert_equals(titleHeading.getAttribute("aria-flowto"), "article1 article2");
titleHeading.ariaFlowToElements = null;
assert_false(titleHeading.hasAttribute("aria-flowto", "Nullifying the IDL attribute should remove the content attribute."));
}, "aria-flowto.");
</script>
@ -378,6 +402,12 @@
listItemOwner.setAttribute("aria-owns", "child1");
assert_array_equals(listItemOwner.ariaOwnsElements, [child1]);
listItemOwner.ariaOwnsElements = [child1, child2];
assert_equals(listItemOwner.getAttribute("aria-owns"), "child1 child2");
listItemOwner.ariaOwnsElements = null;
assert_false(listItemOwner.hasAttribute("aria-owns", "Nullifying the IDL attribute should remove the content attribute."));
}, "aria-owns.");
</script>
@ -477,6 +507,7 @@
</script>
<div id="sameScopeContainer">
<div id="labeledby" aria-labeledby="headingLabel1 headingLabel2">Misspelling</div>
<div id="headingLabel1">Wonderful</div>
<div id="headingLabel2">Fantastic</div>
@ -491,6 +522,8 @@
const headingLabel2 = document.getElementById("headingLabel2")
shadowRoot.appendChild(headingElement);
assert_array_equals(labeledby.ariaLabelledByElements, [headingLabel1, headingLabel2], "aria-labeled by is supported by IDL getter.");
// Explicitly set elements are in a lighter shadow DOM, so that's ok.
headingElement.ariaLabelledByElements = [headingLabel1, headingLabel2];
assert_array_equals(headingElement.ariaLabelledByElements, [headingLabel1, headingLabel2], "Lighter elements are gettable when explicitly set.");

View file

@ -0,0 +1,15 @@
test(() => {
assert_false("getAll" in new Headers());
assert_false("getAll" in Headers.prototype);
}, "Headers object no longer has a getAll() method");
test(() => {
assert_false("type" in new Request("about:blank"));
assert_false("type" in Request.prototype);
}, "'type' getter should not exist on Request objects");
// See https://github.com/whatwg/fetch/pull/979 for the removal
test(() => {
assert_false("trailer" in new Response());
assert_false("trailer" in Response.prototype);
}, "Response object no longer has a trailer getter");

View file

@ -1,4 +0,0 @@
test(() => {
assert_false("getAll" in new Headers)
assert_false("getAll" in Headers.prototype)
}, "Headers object no longer has a getAll() method")

View file

@ -1,11 +0,0 @@
<!DOCTYPE html>
<title>Request.type attribute should not exist</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
var request = new Request("https://domfarolino.com");
test(() => {
assert_equals(request.type, undefined, "request.type should be undefined");
}, "'type' getter should not exist on Request objects");
</script>

View file

@ -1,24 +0,0 @@
<!doctype html>
<title>trailer() test</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<!-- based on /xhr/getresponseheader-chunked-trailer.htm -->
<script>
promise_test(() => {
return fetch("/xhr/resources/chunked.py").then(res => {
assert_equals(res.headers.get("Trailer"), "X-Test-Me")
assert_equals(res.headers.get("X-Test-Me"), null)
assert_equals(res.headers.get("Content-Type"), "text/plain")
return Promise.all([
res.text().then(text => {
assert_equals(text, "First chunk\r\nSecond chunk\r\nYet another (third) chunk\r\nYet another (fourth) chunk\r\n")
}),
res.trailer.then(trailers => {
assert_equals(trailers.get("X-Test-Me"), "Trailer header value")
assert_throws(new TypeError, () => trailers.append("Immutable-My-Ass", "Hi!"))
})
])
})
})
</script>

View file

@ -0,0 +1,85 @@
<!DOCTYPE html>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=/fetch/metadata/resources/helper.js></script>
<script src=/common/utils.js></script>
<body>
<script>
const USER = true;
const FORCED = false;
function create_test(host, user_activated, expectations) {
async_test(t => {
let nonce = token();
let w = window.open("", nonce);
let f = document.createElement('form');
window.addEventListener('message', t.step_func(e => {
if (e.source != w)
return;
assert_header_equals(e.data, expectations,
`{{host}} -> ${host} iframe: ${user_activated ? "user-activated" : "forced"}`);
t.done();
}));
let url = `https://${host}/fetch/metadata/resources/post-to-owner.py`;
f.action = url;
f.target = nonce;
document.body.appendChild(f);
if (user_activated == FORCED) {
f.submit();
} else if (user_activated == USER) {
let s = document.createElement('input');
s.type = "submit";
f.appendChild(s);
test_driver.click(s);
}
}, `{{host}} -> ${host} iframe: ${user_activated ? "user-activated" : "forced"}`);
}
create_test("{{host}}:{{ports[https][0]}}", FORCED, {
"site": "same-origin",
"user": "",
"mode": "navigate",
"dest": "document"
});
create_test("{{hosts[][www]}}:{{ports[https][0]}}", FORCED, {
"site": "same-site",
"user": "",
"mode": "navigate",
"dest": "document"
});
create_test("{{hosts[alt][www]}}:{{ports[https][0]}}", FORCED, {
"site": "cross-site",
"user": "",
"mode": "navigate",
"dest": "document"
});
create_test("{{host}}:{{ports[https][0]}}", USER, {
"site": "same-origin",
"user": "?1",
"mode": "navigate",
"dest": "document"
});
create_test("{{hosts[][www]}}:{{ports[https][0]}}", USER, {
"site": "same-site",
"user": "?1",
"mode": "navigate",
"dest": "document"
});
create_test("{{hosts[alt][www]}}:{{ports[https][0]}}", USER, {
"site": "cross-site",
"user": "?1",
"mode": "navigate",
"dest": "document"
});
</script>

View file

@ -19,6 +19,7 @@ self.onmessage = e => {
self.onmessageerror = e => {
if (state === "we are expecting a messageerror due to the window sending us a SAB") {
assert_equals(e.constructor.name, "ExtendableMessageEvent", "type");
assert_equals(e.data, null, "data");
assert_equals(e.origin, self.origin, "origin");
assert_not_equals(e.source, null, "source");

View file

@ -1,18 +0,0 @@
"use strict";
self.importScripts("/resources/testharness.js");
let state = "start in worker";
self.onmessage = e => {
if (e.data === "start in window") {
assert_equals(state, "start in worker");
e.source.postMessage(state);
state = "waiting for message from the window";
} else if (e.data === "we are expecting a messageerror due to the worker sending us a SAB") {
assert_equals(state, "waiting for message from the window");
e.source.postMessage(new SharedArrayBuffer());
state = "done in worker";
} else {
e.source.postMessage(`worker onmessage was reached when in state "${state}" and data ${e.data}`);
}
};

View file

@ -11,12 +11,14 @@
"use strict";
promise_test(t => {
const scope = "resources/blank.html";
return service_worker_unregister_and_register(t, "resources/serviceworker-failure.js", scope).then(reg => {
return service_worker_unregister_and_register(t, "resources/serviceworker-failure.js", scope)
.then(reg => {
t.add_cleanup(() => service_worker_unregister(t, scope));
return wait_for_state(t, reg.installing, "activated");
})
.then(() => {
return with_iframe(scope);
}).then(iframe => {
.then(() => with_iframe(scope))
.then(iframe => {
t.add_cleanup(() => iframe.remove());
const sw = iframe.contentWindow.navigator.serviceWorker;
let state = "start in window";
@ -40,7 +42,7 @@ promise_test(t => {
assert_equals(e.data, null, "data");
assert_equals(e.origin, self.origin, "origin");
assert_equals(e.source, null, "source");
assert_not_equals(e.source, null, "source");
assert_equals(e.ports.length, 0, "ports length");
state = "done in window";

View file

@ -1,48 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test ServiceWorkerContainer.onmessageerror using SharedArrayBuffer</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script>
"use strict";
promise_test(t => {
const scope = "resources/blank.html";
return service_worker_unregister_and_register(t, "resources/serviceworker-success.js", scope)
.then(reg => {
t.add_cleanup(() => service_worker_unregister(t, scope));
return wait_for_state(t, reg.installing, "activated");
})
.then(() => with_iframe(scope))
.then(iframe => {
t.add_cleanup(() => iframe.remove());
const sw = iframe.contentWindow.navigator.serviceWorker;
let state = "start in window";
return new Promise(resolve => {
sw.onmessage = t.step_func(e => {
if (e.data === "start in worker") {
assert_equals(state, "start in window");
state = "we are expecting a messageerror due to the worker sending us a SAB";
sw.controller.postMessage(state);
} else {
assert_unreached("Got an unexpected message from the service worker: " + e.data);
}
});
sw.onmessageerror = t.step_func(e => {
assert_equals(state, "we are expecting a messageerror due to the worker sending us a SAB");
assert_equals(e.data, null, "data");
assert_equals(e.origin, self.origin, "origin");
assert_not_equals(e.source, null, "source");
assert_equals(e.ports.length, 0, "ports length");
state = "done in window";
resolve();
});
sw.controller.postMessage(state);
});
});
});
</script>

View file

@ -1,2 +0,0 @@
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

View file

@ -0,0 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>link element rel is ASCII case-insensitive (mismatch reference)</title>
<link rel="stylesheet" href="stylesheet.css">
<p>Test passes if background is not red.</p>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>link element rel is ASCII case-insensitive</title>
<link rel="help" href="https://html.spec.whatwg.org/#the-link-element">
<link rel="help" href="https://html.spec.whatwg.org/#attr-link-rel">
<link rel="help" href="https://html.spec.whatwg.org/#linkTypes">
<meta name="assert" content="link element's rel attribute is ASCII case-insensitive.">
<link rel="mismatch" href="link-rel-attribute-ascii-case-insensitive-notref.html">
<!-- Load sheet with a red background (rel attribute value is case-sensitive
equal to "stylesheet") -->
<link rel="stylesheet" href="stylesheet.css">
<!-- Load sheet with white background (rel attribute value is ASCII
case-insensitive equal to "stylesheet") -->
<link rel="StyLeShEeT" href="style.css">
<!-- Do not load sheet with a red background (rel attribute value is
case-insensitive equal to "stylesheet") -->
<link rel="ſtyleſheet" href="stylesheet.css">
<p>Test passes if background is not red.</p>

View file

@ -0,0 +1,29 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
promise_test(async (test) => {
const reg = await navigator.serviceWorker.register('./serviceworker.js', { type: 'module' });
test.add_cleanup(() => reg.unregister());
assert_not_equals(reg.installing, undefined);
}, "Javascript importing JSON Module should load within the context of a service worker");
promise_test(async (test) => {
const reg = await navigator.serviceWorker.register('./module.json', { type: 'module' });
test.add_cleanup(() => reg.unregister());
assert_not_equals(reg.installing, undefined);
}, "JSON Modules should load within the context of a service worker");
promise_test(async (test) => {
const reg = await navigator.serviceWorker.register('./serviceworker-dynamic-import.js', { type: 'module' });
test.add_cleanup(() => reg.unregister());
assert_not_equals(reg.installing, undefined);
reg.installing.postMessage("PING");
const msgEvent = await new Promise(resolve => {
navigator.serviceWorker.onmessage = resolve;
});
assert_equals(msgEvent.data, "FAILED");
}, "JSON Module dynamic import should not load within the context of a service worker");
</script>

View file

@ -0,0 +1,5 @@
onmessage = e => {
e.waitUntil(import("./module.json")
.then(module => e.source.postMessage("LOADED"))
.catch(error => e.source.postMessage("FAILED")));
};

View file

@ -0,0 +1 @@
<p>Test that should not crash

View file

@ -90,7 +90,6 @@ enum RequestRedirect { "follow", "error", "manual" };
readonly attribute boolean ok;
readonly attribute ByteString statusText;
[SameObject] readonly attribute Headers headers;
readonly attribute Promise<Headers> trailer;
[NewObject] Response clone();
};

View file

@ -220,11 +220,6 @@ dictionary RTCPeerConnectionStats : RTCStats {
unsigned long dataChannelsAccepted;
};
dictionary RTCMediaStreamStats : RTCStats {
DOMString streamIdentifier;
sequence<DOMString> trackIds;
};
dictionary RTCRtpTransceiverStats {
DOMString senderId;
DOMString receiverId;
@ -301,7 +296,6 @@ dictionary RTCSctpTransportStats : RTCStats {
dictionary RTCIceCandidateStats : RTCStats {
DOMString transportId;
RTCNetworkType networkType;
DOMString? address;
long port;
DOMString protocol;
@ -311,16 +305,6 @@ dictionary RTCIceCandidateStats : RTCStats {
DOMString relayProtocol;
};
enum RTCNetworkType {
"bluetooth",
"cellular",
"ethernet",
"wifi",
"wimax",
"vpn",
"unknown"
};
dictionary RTCIceCandidatePairStats : RTCStats {
DOMString transportId;
DOMString localCandidateId;
@ -372,12 +356,16 @@ dictionary RTCIceServerStats : RTCStats {
DOMString url;
long port;
DOMString protocol;
RTCNetworkType networkType;
unsigned long totalRequestsSent;
unsigned long totalResponsesReceived;
double totalRoundTripTime;
};
dictionary RTCMediaStreamStats : RTCStats {
DOMString streamIdentifier;
sequence<DOMString> trackIds;
};
dictionary RTCReceiverVideoTrackAttachmentStats : RTCVideoReceiverStats {};
dictionary RTCReceiverAudioTrackAttachmentStats : RTCAudioReceiverStats {};

View file

@ -100,7 +100,7 @@ interface RTCPeerConnection : EventTarget {
readonly attribute boolean? canTrickleIceCandidates;
void restartIce();
RTCConfiguration getConfiguration();
void setConfiguration(RTCConfiguration configuration);
void setConfiguration(optional RTCConfiguration configuration = {});
void close();
attribute EventHandler onnegotiationneeded;
attribute EventHandler onicecandidate;

View file

@ -12,3 +12,34 @@ class ElementLoadPromise {
return document.getElementById(this.element_id);
}
}
// Returns if the image is complete and the lazily loaded image matches the expected image.
function is_image_fully_loaded(image, expected_image) {
if (!image.complete || !expected_image.complete) {
return false;
}
if (image.width != expected_image.width ||
image.height != expected_image.height) {
return false;
}
let canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
let canvasContext = canvas.getContext("2d");
canvasContext.save();
canvasContext.drawImage(image, 0, 0);
let data = canvasContext.getImageData(0, 0, canvas.width, canvas.height).data;
canvasContext.restore();
canvasContext.drawImage(expected_image, 0, 0);
let expected_data = canvasContext.getImageData(0, 0, canvas.width, canvas.height).data;
for (var i = 0; i < data.length; i++) {
if (data[i] != expected_data[i]) {
return false;
}
}
return true;
}

View file

@ -0,0 +1,60 @@
<!DOCTYPE html>
<head>
<title>Test that below-viewport invisible images that are not marked
loading=lazy still load, and block the window load event</title>
<link rel="author" title="Rob Buis" href="mailto:rbuis@igalia.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="common.js"></script>
</head>
<body>
<img id="expected" src='resources/image.png?1'>
<div style="height:10000px;"></div>
<img id="visibility_hidden" style="visibility:hidden;" src='resources/image.png?2'>
<img id="display_none" style="display:none;" src='resources/image.png?3'>
<img id="attribute_hidden" hidden src='resources/image.png?4'>
<img id="js_hidden" src='resources/image.png?5'>.
<script>
document.getElementById("js_hidden").style = 'display:none;';
</script>
</body>
<!--
Marked as tentative until https://github.com/whatwg/html/pull/3752 is landed.
-->
<script>
const expected = document.getElementById("expected");
const visibility_hidden_element = document.getElementById("visibility_hidden");
const display_none_element = document.getElementById("display_none");
const attribute_hidden_element = document.getElementById("attribute_hidden");
const js_hidden_element = document.getElementById("js_hidden");
let has_window_loaded = false;
async_test(function(t) {
window.addEventListener("load", t.step_func(function() {
has_window_loaded = true;
}));
let image_fully_loaded_promise = (element) => {
return new Promise(resolve => {
element.addEventListener("load",
t.step_func(() => {
assert_true(is_image_fully_loaded(element, expected));
assert_false(has_window_loaded);
resolve();
}));
});
}
Promise.all([image_fully_loaded_promise(visibility_hidden_element),
image_fully_loaded_promise(display_none_element),
image_fully_loaded_promise(attribute_hidden_element),
image_fully_loaded_promise(js_hidden_element)]).then(() => {
t.done();
});
}, "Test that below-viewport invisible images that are not marked " +
"loading=lazy still load, and block the window load event");
</script>

View file

@ -0,0 +1,63 @@
<!DOCTYPE html>
<head>
<title>Test that lazily loaded below the viewport invisible
images are not loaded</title>
<link rel="author" title="Rob Buis" href="mailto:rbuis@igalia.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div style="height:10000px;"></div>
<img id="visibility_hidden" style="visibility:hidden;" src='resources/image.png?1' loading="lazy">
<img id="display_none" style="display:none;" src='resources/image.png?2' loading="lazy">
<img id="attribute_hidden" hidden src='resources/image.png?3' loading="lazy">
<img id="js_hidden" src='resources/image.png?4' loading="lazy">
<script>
document.getElementById("js_hidden").style = 'display:none;';
</script>
</body>
<!--
Marked as tentative until https://github.com/whatwg/html/pull/3752 is landed.
-->
<script>
const visibility_hidden_element = document.getElementById("visibility_hidden");
const display_none_element = document.getElementById("display_none");
const attribute_hidden_element = document.getElementById("attribute_hidden");
const js_hidden_element = document.getElementById("js_hidden");
async_test(function(t) {
visibility_hidden_element.onload = e => {
t.step(function() {
t.unreached_func("Invisible image with loading=lazy should be loaded lazily.");
});
};
display_none_element.onload = e => {
t.step(function() {
t.unreached_func("Invisible image with loading=lazy should be loaded lazily.");
});
};
attribute_hidden_element.onload = e => {
t.step(function() {
t.unreached_func("Invisible image with loading=lazy should be loaded lazily.");
});
};
js_hidden_element.onload = e => {
t.step(function() {
t.unreached_func("Invisible image with loading=lazy should be loaded lazily.");
});
};
window.addEventListener("load", t.step_func(function() {
visibility_hidden_element.scrollIntoView();
display_none_element.scrollIntoView();
attribute_hidden_element.scrollIntoView();
js_hidden_element.scrollIntoView();
}));
t.step_timeout(function() { t.done(); }, 2000);
}, "Test that lazily loaded below the viewport invisible images " +
"are not loaded");
</script>

View file

@ -26,6 +26,11 @@ components:
vars:
test-type: wdspec
wpt-crashtest:
chunks: 1
vars:
test-type: crashtest
run-options:
options:
xvfb: true
@ -115,6 +120,8 @@ tasks:
suite: reftest
- vars:
suite: wdspec
- vars:
suite: crashtest
do:
$map:
for:

View file

@ -123,6 +123,8 @@ def test_verify_payload():
'wpt-chrome-dev-reftest-5',
'wpt-firefox-nightly-wdspec-1',
'wpt-chrome-dev-wdspec-1',
'wpt-firefox-nightly-crashtest-1',
'wpt-chrome-dev-crashtest-1',
'lint'}),
("pr_event.json", True, {".taskcluster.yml",".travis.yml","tools/ci/start.sh"},
{'lint',
@ -166,6 +168,7 @@ def test_verify_payload():
'wpt-chrome-stable-testharness-8',
'wpt-chrome-stable-testharness-9',
'wpt-chrome-stable-wdspec-1',
'wpt-chrome-stable-crashtest-1',
'wpt-firefox-stable-reftest-1',
'wpt-firefox-stable-reftest-2',
'wpt-firefox-stable-reftest-3',
@ -188,6 +191,7 @@ def test_verify_payload():
'wpt-firefox-stable-testharness-8',
'wpt-firefox-stable-testharness-9',
'wpt-firefox-stable-wdspec-1',
'wpt-firefox-stable-crashtest-1',
'wpt-webkitgtk_minibrowser-nightly-reftest-1',
'wpt-webkitgtk_minibrowser-nightly-reftest-2',
'wpt-webkitgtk_minibrowser-nightly-reftest-3',
@ -209,7 +213,8 @@ def test_verify_payload():
'wpt-webkitgtk_minibrowser-nightly-testharness-7',
'wpt-webkitgtk_minibrowser-nightly-testharness-8',
'wpt-webkitgtk_minibrowser-nightly-testharness-9',
'wpt-webkitgtk_minibrowser-nightly-wdspec-1'})
'wpt-webkitgtk_minibrowser-nightly-wdspec-1',
'wpt-webkitgtk_minibrowser-nightly-crashtest-1'})
])
def test_schedule_tasks(event_path, is_pr, files_changed, expected):
with mock.patch("tools.ci.tc.decision.get_fetch_rev", return_value=(None, None, None)):

View file

@ -329,6 +329,17 @@ class VisualTest(URLManifestItem):
item_type = "visual"
class CrashTest(URLManifestItem):
__slots__ = ()
item_type = "crashtest"
@property
def timeout(self):
# type: () -> Optional[Text]
return None
class WebDriverSpecTest(URLManifestItem):
__slots__ = ()

View file

@ -6,7 +6,7 @@ from six import iteritems, iterkeys, itervalues, string_types, binary_type, text
from . import vcs
from .item import (ConformanceCheckerTest, ManifestItem, ManualTest, RefTest, RefTestNode,
SupportFile, TestharnessTest, VisualTest, WebDriverSpecTest)
SupportFile, TestharnessTest, VisualTest, WebDriverSpecTest, CrashTest)
from .log import get_logger
from .sourcefile import SourceFile
from .utils import from_os_path, to_os_path
@ -50,6 +50,7 @@ class ManifestVersionMismatch(ManifestError):
item_classes = {"testharness": TestharnessTest,
"reftest": RefTest,
"reftest_node": RefTestNode,
"crashtest": CrashTest,
"manual": ManualTest,
"wdspec": WebDriverSpecTest,
"conformancechecker": ConformanceCheckerTest,

View file

@ -34,7 +34,7 @@ import html5lib
from . import XMLParser
from .item import (ManifestItem, ManualTest, WebDriverSpecTest, RefTestNode, TestharnessTest,
SupportFile, ConformanceCheckerTest, VisualTest)
SupportFile, CrashTest, ConformanceCheckerTest, VisualTest)
from .utils import ContextManagerBytesIO, cached_property
wd_pattern = "*.py"
@ -408,6 +408,11 @@ class SourceFile(object):
be a reference file (not a reftest)"""
return "/reference/" in self.url or bool(reference_file_re.search(self.name))
@property
def name_is_crashtest(self):
# type: () -> bool
return self.type_flag == "crash" or "crashtests" in self.dir_path.split(os.path.sep)
@property
def markup_type(self):
# type: () -> Optional[Text]
@ -820,6 +825,15 @@ class SourceFile(object):
self.rel_url
)]
elif self.name_is_crashtest:
rv = CrashTest.item_type, [
CrashTest(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url
)]
elif self.name_is_multi_global:
globals = b""
script_metadata = self.script_metadata

View file

@ -3,7 +3,8 @@ from .base import get_timeout_multiplier # noqa: F401
from ..webdriver_server import ChromeDriverServer
from ..executors import executor_kwargs as base_executor_kwargs
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
WebDriverRefTestExecutor) # noqa: F401
WebDriverRefTestExecutor, # noqa: F401
WebDriverCrashtestExecutor) # noqa: F401
from ..executors.executorchrome import ChromeDriverWdspecExecutor # noqa: F401
@ -12,7 +13,8 @@ __wptrunner__ = {"product": "chrome",
"browser": "ChromeBrowser",
"executor": {"testharness": "WebDriverTestharnessExecutor",
"reftest": "WebDriverRefTestExecutor",
"wdspec": "ChromeDriverWdspecExecutor"},
"wdspec": "ChromeDriverWdspecExecutor",
"crashtest": "WebDriverCrashtestExecutor"},
"browser_kwargs": "browser_kwargs",
"executor_kwargs": "executor_kwargs",
"env_extras": "env_extras",

View file

@ -23,7 +23,8 @@ from .base import (get_free_port,
from ..executors import executor_kwargs as base_executor_kwargs
from ..executors.executormarionette import (MarionetteTestharnessExecutor, # noqa: F401
MarionetteRefTestExecutor, # noqa: F401
MarionetteWdspecExecutor) # noqa: F401
MarionetteWdspecExecutor, # noqa: F401
MarionetteCrashtestExecutor) # noqa: F401
here = os.path.join(os.path.split(__file__)[0])
@ -31,7 +32,8 @@ here = os.path.join(os.path.split(__file__)[0])
__wptrunner__ = {"product": "firefox",
"check_args": "check_args",
"browser": "FirefoxBrowser",
"executor": {"testharness": "MarionetteTestharnessExecutor",
"executor": {"crashtest": "MarionetteCrashtestExecutor",
"testharness": "MarionetteTestharnessExecutor",
"reftest": "MarionetteRefTestExecutor",
"wdspec": "MarionetteWdspecExecutor"},
"browser_kwargs": "browser_kwargs",

View file

@ -121,6 +121,9 @@ def pytest_result_converter(self, test, data):
return (harness_result, subtest_results)
def crashtest_result_converter(self, test, result):
return test.result_cls(**result), []
class ExecutorException(Exception):
def __init__(self, status, message):
self.status = status
@ -316,6 +319,10 @@ class RefTestExecutor(TestExecutor):
self.screenshot_cache = screenshot_cache
class CrashtestExecutor(TestExecutor):
convert_result = crashtest_result_converter
class RefTestImplementation(object):
def __init__(self, executor):
self.timeout_multiplier = executor.timeout_multiplier
@ -573,6 +580,9 @@ class WdspecRun(object):
class ConnectionlessBaseProtocolPart(BaseProtocolPart):
def load(self, url):
pass
def execute_script(self, script, asynchronous=False):
pass

View file

@ -13,6 +13,7 @@ pytestrunner = None
here = os.path.join(os.path.split(__file__)[0])
from .base import (CallbackHandler,
CrashtestExecutor,
RefTestExecutor,
RefTestImplementation,
TestharnessExecutor,
@ -80,6 +81,9 @@ class MarionetteBaseProtocolPart(BaseProtocolPart):
def set_window(self, handle):
self.marionette.switch_to_window(handle)
def load(self, url):
self.marionette.navigate(url)
def wait(self):
try:
socket_timeout = self.marionette.client.socket_timeout
@ -790,8 +794,8 @@ class MarionetteRefTestExecutor(RefTestExecutor):
with open(os.path.join(here, "reftest.js")) as f:
self.script = f.read()
with open(os.path.join(here, "reftest-wait_webdriver.js")) as f:
self.wait_script = f.read()
with open(os.path.join(here, "test-wait.js")) as f:
self.wait_script = f.read() % {"classname": "reftest-wait"}
def setup(self, runner):
super(self.__class__, self).setup(runner)
@ -935,10 +939,77 @@ class InternalRefTestImplementation(RefTestImplementation):
self.logger.warning(traceback.format_exc(e))
class GeckoDriverProtocol(WebDriverProtocol):
server_cls = GeckoDriverServer
class MarionetteWdspecExecutor(WdspecExecutor):
protocol_cls = GeckoDriverProtocol
class MarionetteCrashtestExecutor(CrashtestExecutor):
def __init__(self, browser, server_config, timeout_multiplier=1,
debug_info=None, capabilities=None, debug=False,
ccov=False, **kwargs):
"""Marionette-based executor for testharness.js tests"""
CrashtestExecutor.__init__(self, browser, server_config,
timeout_multiplier=timeout_multiplier,
debug_info=debug_info)
self.protocol = MarionetteProtocol(self,
browser,
capabilities,
timeout_multiplier,
kwargs["e10s"],
ccov)
self.original_pref_values = {}
self.debug = debug
with open(os.path.join(here, "test-wait.js")) as f:
self.wait_script = f.read() % {"classname": "test-wait"}
if marionette is None:
do_delayed_imports()
def is_alive(self):
return self.protocol.is_alive
def on_environment_change(self, new_environment):
self.protocol.on_environment_change(self.last_environment, new_environment)
def do_test(self, test):
timeout = (test.timeout * self.timeout_multiplier if self.debug_info is None
else None)
success, data = ExecuteAsyncScriptRun(self.logger,
self.do_crashtest,
self.protocol,
self.test_url(test),
timeout,
self.extra_timeout).run()
status = None
if not success:
status = data[0]
if self.debug and (success or status not in ("CRASH", "INTERNAL-ERROR")):
assertion_count = self.protocol.asserts.get()
if assertion_count is not None:
data["extra"] = {"assertion_count": assertion_count}
if success:
return self.convert_result(test, data)
return (test.result_cls(**data), [])
def do_crashtest(self, protocol, url, timeout):
if self.protocol.coverage.is_enabled:
self.protocol.coverage.reset()
protocol.base.load(url)
protocol.base.execute_script(self.wait_script, asynchronous=True)
if self.protocol.coverage.is_enabled:
self.protocol.coverage.dump()
return {"status": "PASS",
"message": None}

View file

@ -76,6 +76,9 @@ class ServoBaseProtocolPart(BaseProtocolPart):
def set_window(self, handle):
pass
def load(self, url):
pass
class ServoWebDriverProtocol(Protocol):
implements = [ServoBaseProtocolPart]

View file

@ -8,6 +8,7 @@ import urlparse
import uuid
from .base import (CallbackHandler,
CrashtestExecutor,
RefTestExecutor,
RefTestImplementation,
TestharnessExecutor,
@ -58,6 +59,9 @@ class WebDriverBaseProtocolPart(BaseProtocolPart):
def set_window(self, handle):
self.webdriver.window_handle = handle
def load(self, url):
self.webdriver.url = url
def wait(self):
while True:
try:
@ -449,8 +453,8 @@ class WebDriverRefTestExecutor(RefTestExecutor):
self.close_after_done = close_after_done
self.has_window = False
with open(os.path.join(here, "reftest-wait_webdriver.js")) as f:
self.wait_script = f.read()
with open(os.path.join(here, "test-wait.js")) as f:
self.wait_script = f.read() % {"classname": "reftest-wait"}
def reset(self):
self.implementation.reset()
@ -487,15 +491,55 @@ class WebDriverRefTestExecutor(RefTestExecutor):
self.extra_timeout).run()
def _screenshot(self, protocol, url, timeout):
webdriver = protocol.webdriver
webdriver.url = url
self.protocol.base.load(url)
webdriver.execute_async_script(self.wait_script)
self.protocol.base.execute_script(self.wait_script, True)
screenshot = webdriver.screenshot()
screenshot = self.protocol.webdriver.screenshot()
# strip off the data:img/png, part of the url
if screenshot.startswith("data:image/png;base64,"):
screenshot = screenshot.split(",", 1)[1]
return screenshot
class WebDriverCrashtestExecutor(CrashtestExecutor):
def __init__(self, browser, server_config, timeout_multiplier=1,
screenshot_cache=None, close_after_done=True,
debug_info=None, capabilities=None, **kwargs):
"""WebDriver-based executor for reftests"""
CrashtestExecutor.__init__(self,
browser,
server_config,
screenshot_cache=screenshot_cache,
timeout_multiplier=timeout_multiplier,
debug_info=debug_info)
self.protocol = WebDriverProtocol(self, browser,
capabilities=capabilities)
with open(os.path.join(here, "test-wait.js")) as f:
self.wait_script = f.read() % {"classname": "test-wait"}
def do_test(self, test):
timeout = (test.timeout * self.timeout_multiplier if self.debug_info is None
else None)
success, data = WebDriverRun(self.logger,
self.do_crashtest,
self.protocol,
self.test_url(test),
timeout,
self.extra_timeout).run()
if success:
return self.convert_result(test, data)
return (test.result_cls(**data), [])
def do_crashtest(self, protocol, url, timeout):
protocol.base.load(url)
protocol.base.execute_script(self.wait_script, asynchronous=True)
return {"status": "PASS",
"message": None}

View file

@ -147,6 +147,13 @@ class BaseProtocolPart(ProtocolPart):
context."""
pass
@abstractmethod
def load(self, url):
"""Load a url in the current browsing context
:param url: The url to load"""
pass
class TestharnessProtocolPart(ProtocolPart):
"""Protocol part required to run testharness tests."""

View file

@ -32,7 +32,7 @@ function wait_paints() {
}
function screenshot_if_ready() {
if (root.classList.contains("reftest-wait") &&
if (root.classList.contains("%(classname)s") &&
observer === null) {
observer = new MutationObserver(wait_paints);
observer.observe(root, {attributes: true});

View file

@ -1,3 +1,5 @@
from six.moves import xrange
class NodeVisitor(object):
def visit(self, node):
# This is ugly as hell, but we don't have multimethods and

View file

@ -15,6 +15,7 @@
from __future__ import unicode_literals
from six import binary_type, text_type, BytesIO
from six.moves import xrange
from .node import (Node, AtomNode, BinaryExpressionNode, BinaryOperatorNode,
ConditionalNode, DataNode, IndexNode, KeyValueNode, ListNode,
@ -541,7 +542,7 @@ class Parser(object):
raise
def consume(self):
self.token = self.token_generator.next()
self.token = next(self.token_generator)
def expect(self, type, value=None):
if self.token[0] != type:

View file

@ -1,23 +1,17 @@
import pytest
import sys
import unittest
from six.moves import cStringIO as StringIO
from .. import parser
# There aren't many tests here because it turns out to be way more convenient to
# use test_serializer for the majority of cases
@pytest.mark.xfail(sys.version[0] == "3",
reason="wptmanifest.parser doesn't support py3")
class TestExpression(unittest.TestCase):
def setUp(self):
self.parser = parser.Parser()
def parse(self, input_str):
return self.parser.parse(StringIO(input_str))
return self.parser.parse(input_str)
def compare(self, input_text, expected):
actual = self.parse(input_text)
@ -32,7 +26,7 @@ class TestExpression(unittest.TestCase):
def test_expr_0(self):
self.compare(
"""
b"""
key:
if x == 1 : value""",
["DataNode", None,
@ -49,7 +43,7 @@ key:
def test_expr_1(self):
self.compare(
"""
b"""
key:
if not x and y : value""",
["DataNode", None,
@ -69,7 +63,7 @@ key:
def test_expr_2(self):
self.compare(
"""
b"""
key:
if x == 1 : [value1, value2]""",
["DataNode", None,
@ -88,7 +82,7 @@ key:
def test_expr_3(self):
self.compare(
"""
b"""
key:
if x == 1: 'if b: value'""",
["DataNode", None,
@ -105,15 +99,15 @@ key:
def test_atom_0(self):
with self.assertRaises(parser.ParseError):
self.parse("key: @Unknown")
self.parse(b"key: @Unknown")
def test_atom_1(self):
with self.assertRaises(parser.ParseError):
self.parse("key: @true")
self.parse(b"key: @true")
def test_if_1(self):
with self.assertRaises(parser.ParseError):
self.parse("key: if foo")
self.parse(b"key: if foo")
if __name__ == "__main__":

View file

@ -6,7 +6,7 @@ from collections import defaultdict
from .wptmanifest.parser import atoms
atom_reset = atoms["Reset"]
enabled_tests = {"testharness", "reftest", "wdspec"}
enabled_tests = {"testharness", "reftest", "wdspec", "crashtest"}
class Result(object):
@ -71,6 +71,12 @@ class WdspecSubtestResult(SubtestResult):
statuses = {"PASS", "FAIL", "ERROR"}
class CrashtestResult(Result):
default_expected = "PASS"
statuses = {"PASS", "ERROR", "INTERNAL-ERROR", "TIMEOUT", "EXTERNAL-TIMEOUT",
"CRASH"}
def get_run_info(metadata_root, product, **kwargs):
return RunInfo(metadata_root, product, **kwargs)
@ -546,7 +552,6 @@ class ReftestTest(Test):
class WdspecTest(Test):
result_cls = WdspecResult
subtest_result_cls = WdspecSubtestResult
test_type = "wdspec"
@ -555,10 +560,16 @@ class WdspecTest(Test):
long_timeout = 180 # 3 minutes
class CrashTest(Test):
result_cls = CrashtestResult
test_type = "crashtest"
manifest_test_cls = {"reftest": ReftestTest,
"testharness": TestharnessTest,
"manual": ManualTest,
"wdspec": WdspecTest}
"wdspec": WdspecTest,
"crashtest": CrashTest}
def from_manifest(manifest_file, manifest_test, inherit_metadata, test_metadata):

View file

@ -21,6 +21,7 @@ self.onmessage = e => {
self.onmessageerror = e => {
if (state === "we are expecting a messageerror due to the window sending us a WebAssembly.Module") {
assert_equals(e.constructor.name, "ExtendableMessageEvent", "type");
assert_equals(e.data, null, "data");
assert_equals(e.origin, self.origin, "origin");
assert_not_equals(e.source, null, "source");

View file

@ -1,19 +0,0 @@
"use strict";
self.importScripts("/resources/testharness.js");
self.importScripts("./create-empty-wasm-module.js");
let state = "start in worker";
self.onmessage = e => {
if (e.data === "start in window") {
assert_equals(state, "start in worker");
e.source.postMessage(state);
state = "waiting for message from the window";
} else if (e.data === "we are expecting a messageerror due to the worker sending us a WebAssembly.Module") {
assert_equals(state, "waiting for message from the window");
e.source.postMessage(createEmptyWasmModule());
state = "done in worker";
} else {
e.source.postMessage(`worker onmessage was reached when in state "${state}" and data ${e.data}`);
}
};

View file

@ -11,12 +11,14 @@
"use strict";
promise_test(t => {
const scope = "resources/blank.html";
return service_worker_unregister_and_register(t, "resources/serviceworker-failure.js", scope).then(reg => {
return service_worker_unregister_and_register(t, "resources/serviceworker-failure.js", scope)
.then(reg => {
t.add_cleanup(() => service_worker_unregister(t, scope));
return wait_for_state(t, reg.installing, "activated");
})
.then(() => {
return with_iframe(scope);
}).then(iframe => {
.then(() => with_iframe(scope))
.then(iframe => {
t.add_cleanup(() => iframe.remove());
const sw = iframe.contentWindow.navigator.serviceWorker;
let state = "start in window";
@ -40,7 +42,7 @@ promise_test(t => {
assert_equals(e.data, null, "data");
assert_equals(e.origin, self.origin, "origin");
assert_equals(e.source, null, "source");
assert_not_equals(e.source, null, "source");
assert_equals(e.ports.length, 0, "ports length");
state = "done in window";

View file

@ -1,49 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test ServiceWorkerContainer.onmessageerror using WebAssembly.Module</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script src="./resources/create-empty-wasm-module.js"></script>
<script>
"use strict";
promise_test(t => {
const scope = "resources/blank.html";
return service_worker_unregister_and_register(t, "resources/serviceworker-success.js", scope)
.then(reg => {
t.add_cleanup(() => service_worker_unregister(t, scope));
return wait_for_state(t, reg.installing, "activated");
})
.then(() => with_iframe(scope))
.then(iframe => {
t.add_cleanup(() => iframe.remove());
const sw = iframe.contentWindow.navigator.serviceWorker;
let state = "start in window";
return new Promise(resolve => {
sw.onmessage = t.step_func(e => {
if (e.data === "start in worker") {
assert_equals(state, "start in window");
state = "we are expecting a messageerror due to the worker sending us a WebAssembly.Module";
sw.controller.postMessage(state);
} else {
assert_unreached("Got an unexpected message from the service worker: " + e.data);
}
});
sw.onmessageerror = t.step_func(e => {
assert_equals(state, "we are expecting a messageerror due to the worker sending us a WebAssembly.Module");
assert_equals(e.data, null, "data");
assert_equals(e.origin, self.origin, "origin");
assert_not_equals(e.source, null, "source");
assert_equals(e.ports.length, 0, "ports length");
state = "done in window";
resolve();
});
sw.controller.postMessage(state);
});
});
});
</script>