mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Update web-platform-tests to revision 0ed072539aa45d3a5a67c9164b243d27873f257c
This commit is contained in:
parent
0954871992
commit
e613cfd108
76 changed files with 1109 additions and 703 deletions
|
@ -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
|
@ -0,0 +1,2 @@
|
|||
[width-047.xht]
|
||||
expected: FAIL
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[response-trailer.html]
|
||||
type: testharness
|
||||
[trailer() test]
|
||||
expected: FAIL
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[window-serviceworker-success.https.html]
|
||||
[Test ServiceWorkerContainer.onmessageerror using SharedArrayBuffer]
|
||||
expected: FAIL
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[window-serviceworker-success.https.html]
|
||||
[Test ServiceWorkerContainer.onmessageerror using WebAssembly.Module]
|
||||
expected: FAIL
|
||||
|
|
@ -3,5 +3,5 @@
|
|||
expected: FAIL
|
||||
|
||||
[test_element_in_collection]
|
||||
expected:
|
||||
if os == "mac": FAIL
|
||||
expected: FAIL
|
||||
|
||||
|
|
5
tests/wpt/metadata/webmessaging/with-ports/018.html.ini
Normal file
5
tests/wpt/metadata/webmessaging/with-ports/018.html.ini
Normal file
|
@ -0,0 +1,5 @@
|
|||
[018.html]
|
||||
expected: TIMEOUT
|
||||
[origin of the script that invoked the method, javascript:]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[017.html]
|
||||
expected: TIMEOUT
|
||||
[origin of the script that invoked the method, about:blank]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[018.html]
|
||||
expected: TIMEOUT
|
||||
[origin of the script that invoked the method, javascript:]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -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:
|
||||
|
|
|
@ -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>
|
||||
|
|
22
tests/wpt/web-platform-tests/docs/writing-tests/crashtest.md
Normal file
22
tests/wpt/web-platform-tests/docs/writing-tests/crashtest.md
Normal 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).
|
|
@ -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/)
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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");
|
|
@ -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")
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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");
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
Cross-Origin-Embedder-Policy: require-corp
|
|
@ -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";
|
||||
|
|
|
@ -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>
|
|
@ -1,2 +0,0 @@
|
|||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1,5 @@
|
|||
onmessage = e => {
|
||||
e.waitUntil(import("./module.json")
|
||||
.then(module => e.source.postMessage("LOADED"))
|
||||
.catch(error => e.source.postMessage("FAILED")));
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
import './module.json';
|
|
@ -0,0 +1 @@
|
|||
<p>Test that should not crash
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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 {};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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:
|
||||
|
|
|
@ -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)):
|
||||
|
|
|
@ -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__ = ()
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -76,6 +76,9 @@ class ServoBaseProtocolPart(BaseProtocolPart):
|
|||
def set_window(self, handle):
|
||||
pass
|
||||
|
||||
def load(self, url):
|
||||
pass
|
||||
|
||||
|
||||
class ServoWebDriverProtocol(Protocol):
|
||||
implements = [ServoBaseProtocolPart]
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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});
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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__":
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
};
|
|
@ -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";
|
||||
|
|
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue