mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Update web-platform-tests to revision 548818eee08f7a6e31b9706b352b5d44b2f6d024
This commit is contained in:
parent
82fd8d1daf
commit
5e74467d68
112 changed files with 1704 additions and 536 deletions
|
@ -7,7 +7,7 @@
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Opening a blob URL in a new window immediately before revoking it works.]
|
[Opening a blob URL in a new window immediately before revoking it works.]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
|
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,2 +1,2 @@
|
||||||
[no-transition-from-ua-to-blocking-stylesheet.html]
|
[no-transition-from-ua-to-blocking-stylesheet.html]
|
||||||
expected: TIMEOUT
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
[MediaQueryList-extends-EventTarget.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[removeEventListener removes listener]
|
||||||
|
expected: NOTRUN
|
||||||
|
|
||||||
|
[addEventListener "once" option is respected]
|
||||||
|
expected: TIMEOUT
|
||||||
|
|
|
@ -84,3 +84,45 @@
|
||||||
[Inserting a custom element into a detached shadow tree that belongs to an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
|
[Inserting a custom element into a detached shadow tree that belongs to an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the <template>'s content of a custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the <template>'s content of a custom element from the owner document into an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the <template>'s content of a custom element from the owner document into the document of an iframe must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the shadow host's shadow of a custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the shadow host's shadow of a custom element from the owner document into an HTML document fetched by XHR must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the shadow host's shadow of a custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the <template>'s content of a custom element from the owner document into a new document must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the shadow host's shadow of a custom element from the owner document into an HTML document created by createDocument must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the <template>'s content of a custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the <template>'s content of a custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the shadow host's shadow of a custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the shadow host's shadow of a custom element from the owner document into the document of an iframe must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the shadow host's shadow of a custom element from the owner document into a new document must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Moving the <template>'s content of a custom element from the owner document into an HTML document created by createDocument must enqueue and invoke adoptedCallback]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
16
tests/wpt/metadata/dom/nodes/adoption.window.js.ini
Normal file
16
tests/wpt/metadata/dom/nodes/adoption.window.js.ini
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[adoption.window.html]
|
||||||
|
[appendChild() and DocumentFragment]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[appendChild() and ShadowRoot]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[adoptNode() and ShadowRoot]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[adoptNode() and DocumentFragment with host]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[appendChild() and DocumentFragment with host]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
[Redirect 307 with HEAD]
|
[Redirect 307 with HEAD]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Redirect 303 with TESTING]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
||||||
[redirect-method.any.html]
|
[redirect-method.any.html]
|
||||||
[Redirect 301 with GET]
|
[Redirect 301 with GET]
|
||||||
|
@ -79,3 +82,6 @@
|
||||||
[Redirect 307 with HEAD]
|
[Redirect 307 with HEAD]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Redirect 303 with TESTING]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -309,3 +309,24 @@
|
||||||
[<iframe>: separate response Content-Type: */* text/html]
|
[<iframe>: separate response Content-Type: */* text/html]
|
||||||
expected: FAIL
|
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
|
||||||
|
|
||||||
|
[<iframe>: separate response Content-Type: text/html */*]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -11,3 +11,6 @@
|
||||||
[X-Content-Type-Options%3A%20nosniff%0C]
|
[X-Content-Type-Options%3A%20nosniff%0C]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[X-Content-Type-Options%3A%20'NosniFF']
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
|
|
||||||
[Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.]
|
[Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.]
|
||||||
expected: TIMEOUT
|
expected: FAIL
|
||||||
|
|
||||||
[Embedded credentials matching the top-level are not treated as network errors for same-origin URLs.]
|
[Embedded credentials matching the top-level are not treated as network errors for same-origin URLs.]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[traverse_the_history_1.html]
|
|
||||||
[Multiple history traversals from the same task]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[traverse_the_history_5.html]
|
||||||
|
[Multiple history traversals, last would be aborted]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[document-domain-nested-navigate.window.html]
|
||||||
|
[Navigated frame to about:blank and document.domain]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[supported-elements.html]
|
[supported-elements.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[Contenteditable element should support autofocus]
|
[Contenteditable element should support autofocus]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Area element should support autofocus]
|
[Area element should support autofocus]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[Host element with delegatesFocus should support autofocus]
|
[Host element with delegatesFocus should support autofocus]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -2,3 +2,6 @@
|
||||||
[Mutating the style element: mutating a Comment node]
|
[Mutating the style element: mutating a Comment node]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Mutating the style element: inserting an empty DocumentFragment node]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
[iframe_sandbox_popups_escaping-3.html]
|
[iframe_sandbox_popups_escaping-3.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
|
||||||
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
||||||
expected: TIMEOUT
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -90,3 +90,12 @@
|
||||||
[[INPUT in NUMBER status\] The value attribute is empty string]
|
[[INPUT in NUMBER status\] The value attribute is empty string]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[[INPUT in NUMBER status\] Step mismatch when step is a very small floating number and value is not its integral multiple]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[[INPUT in NUMBER status\] No step mismatch when step is a floating number in exponent format and value is its integral multiple]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[[INPUT in NUMBER status\] No step mismatch when step is a floating number and value is its integral multiple]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Check that rel=noopener with target=_top does a normal load]
|
[Check that rel=noopener with target=_top does a normal load]
|
||||||
expected: TIMEOUT
|
expected: FAIL
|
||||||
|
|
||||||
[Check that targeting of rel=noopener with a given name reuses an existing window with that name]
|
[Check that targeting of rel=noopener with a given name reuses an existing window with that name]
|
||||||
expected: NOTRUN
|
expected: NOTRUN
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[crossorigin-sandwich-TAO.sub.html]
|
[crossorigin-sandwich-TAO.sub.html]
|
||||||
|
expected: ERROR
|
||||||
[There should be one entry.]
|
[There should be one entry.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[018.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[origin of the script that invoked the method, javascript:]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[017.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[origin of the script that invoked the method, about:blank]
|
||||||
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[018.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[origin of the script that invoked the method, javascript:]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -362,7 +362,6 @@ jobs:
|
||||||
- template: tools/ci/azure/pip_install.yml
|
- template: tools/ci/azure/pip_install.yml
|
||||||
parameters:
|
parameters:
|
||||||
packages: virtualenv
|
packages: virtualenv
|
||||||
- template: tools/ci/azure/install_fonts.yml
|
|
||||||
- template: tools/ci/azure/install_certs.yml
|
- template: tools/ci/azure/install_certs.yml
|
||||||
- template: tools/ci/azure/install_safari.yml
|
- template: tools/ci/azure/install_safari.yml
|
||||||
- template: tools/ci/azure/update_hosts.yml
|
- template: tools/ci/azure/update_hosts.yml
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>setTransform with DOMMatrix behaves correctly</title>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<link rel="help" href="https://drafts.css-houdini.org/css-paint-api/">
|
||||||
|
<link rel="match" href="setTransform-ref.html">
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#foo {
|
||||||
|
background: paint(foo);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="/common/reftest-wait.js"></script>
|
||||||
|
<script src="/common/worklet-reftest.js"></script>
|
||||||
|
<body>
|
||||||
|
<div id="foo" class="container"></div>
|
||||||
|
|
||||||
|
<script id="code" type="text/worklet">
|
||||||
|
registerPaint('foo', class {
|
||||||
|
paint(ctx, geom) {
|
||||||
|
ctx.fillStyle = 'green';
|
||||||
|
let m = ctx.getTransform();
|
||||||
|
m.a = 2;
|
||||||
|
m.d = 2;
|
||||||
|
ctx.setTransform(m);
|
||||||
|
ctx.fillRect(0, 0, 50, 50);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, document.getElementById('code').textContent);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>setTransform with DOMMatrix behaves correctly</title>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<link rel="help" href="https://drafts.css-houdini.org/css-paint-api/">
|
||||||
|
<link rel="match" href="setTransform-ref.html">
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#foo {
|
||||||
|
background: paint(foo);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="/common/reftest-wait.js"></script>
|
||||||
|
<script src="/common/worklet-reftest.js"></script>
|
||||||
|
<body>
|
||||||
|
<div id="foo" class="container"></div>
|
||||||
|
|
||||||
|
<script id="code" type="text/worklet">
|
||||||
|
registerPaint('foo', class {
|
||||||
|
paint(ctx, geom) {
|
||||||
|
ctx.fillStyle = 'green';
|
||||||
|
ctx.setTransform({a: 2, d: 2});
|
||||||
|
ctx.fillRect(0, 0, 50, 50);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, document.getElementById('code').textContent);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>setTransform with NaN should be ignored</title>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<link rel="help" href="https://drafts.css-houdini.org/css-paint-api/">
|
||||||
|
<link rel="match" href="setTransform-ref.html">
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#foo {
|
||||||
|
background: paint(foo);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="/common/reftest-wait.js"></script>
|
||||||
|
<script src="/common/worklet-reftest.js"></script>
|
||||||
|
<body>
|
||||||
|
<div id="foo" class="container"></div>
|
||||||
|
|
||||||
|
<script id="code" type="text/worklet">
|
||||||
|
registerPaint('foo', class {
|
||||||
|
paint(ctx, geom) {
|
||||||
|
ctx.fillStyle = 'green';
|
||||||
|
// Set to a NaN should be ignored.
|
||||||
|
ctx.setTransform({a: NaN, d:2});
|
||||||
|
ctx.fillRect(0, 0, 100, 100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, document.getElementById('code').textContent);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>setTransform with Infinity should be ignored</title>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<link rel="help" href="https://drafts.css-houdini.org/css-paint-api/">
|
||||||
|
<link rel="match" href="setTransform-ref.html">
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#foo {
|
||||||
|
background: paint(foo);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="/common/reftest-wait.js"></script>
|
||||||
|
<script src="/common/worklet-reftest.js"></script>
|
||||||
|
<body>
|
||||||
|
<div id="foo" class="container"></div>
|
||||||
|
|
||||||
|
<script id="code" type="text/worklet">
|
||||||
|
registerPaint('foo', class {
|
||||||
|
paint(ctx, geom) {
|
||||||
|
ctx.fillStyle = 'green';
|
||||||
|
// Set to Infinity should be ignored.
|
||||||
|
ctx.setTransform({a: Infinity, d:2});
|
||||||
|
ctx.fillRect(0, 0, 100, 100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, document.getElementById('code').textContent);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<canvas id ="canvas" width="200" height="200"></canvas>
|
||||||
|
<script>
|
||||||
|
var ctx = document.getElementById('canvas').getContext('2d');
|
||||||
|
ctx.fillStyle = 'green';
|
||||||
|
let m = ctx.getTransform();
|
||||||
|
m.a = 2;
|
||||||
|
m.d = 2;
|
||||||
|
ctx.setTransform(m);
|
||||||
|
ctx.fillRect(0, 0, 50, 50);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1432">
|
||||||
|
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
||||||
|
<style>
|
||||||
|
#containing-block {
|
||||||
|
position: relative;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: red;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#containing-block > div {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#inner-flex {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
inline-size: 50px;
|
||||||
|
block-size: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||||
|
<div id="containing-block" style="flex-direction: row;">
|
||||||
|
<div id="inner-flex" style="margin: 10px; height: 100px;">
|
||||||
|
<div style="position: absolute; top: 0; height: 100px; background: green;">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="height: 100px; background: green;"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1432">
|
||||||
|
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
||||||
|
<style>
|
||||||
|
#containing-block {
|
||||||
|
position: relative;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: red;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#containing-block > div {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#inner-flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
inline-size: 50px;
|
||||||
|
block-size: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||||
|
<div id="containing-block" style="flex-direction: column;">
|
||||||
|
<div id="inner-flex" style="margin: 10px; width: 100px;">
|
||||||
|
<div style="position: absolute; left: 0; width: 100px; background: green; writing-mode: vertical-rl;">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 100px; background: green;"></div>
|
||||||
|
</div>
|
|
@ -2,6 +2,7 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>CSS Reftest Reference</title>
|
<title>CSS Reftest Reference</title>
|
||||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
|
<link rel="mismatch" href="marker-font-variant-numeric-normal-ref.html">
|
||||||
<style>
|
<style>
|
||||||
@font-face {
|
@font-face {
|
||||||
/* This font looks different with 'font-variant-numeric: tabular-nums' */
|
/* This font looks different with 'font-variant-numeric: tabular-nums' */
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
|
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
|
||||||
<link rel="match" href="marker-font-variant-numeric-default-ref.html">
|
<link rel="match" href="marker-font-variant-numeric-default-ref.html">
|
||||||
<link rel="mismatch" href="marker-font-variant-numeric-normal-ref.html">
|
|
||||||
<meta name="assert" content="Checks that the markers have the same width thanks to 'font-variant-numeric: tabular-nums', and thus the black boxes are perfectly aligned">
|
<meta name="assert" content="Checks that the markers have the same width thanks to 'font-variant-numeric: tabular-nums', and thus the black boxes are perfectly aligned">
|
||||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>CSS Reftest Reference</title>
|
<title>CSS Reftest Reference</title>
|
||||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
|
<link rel="mismatch" href="marker-font-variant-numeric-default-ref.html">
|
||||||
<style>
|
<style>
|
||||||
@font-face {
|
@font-face {
|
||||||
/* This font looks different with 'font-variant-numeric: tabular-nums' */
|
/* This font looks different with 'font-variant-numeric: tabular-nums' */
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
|
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
|
||||||
<link rel="match" href="marker-font-variant-numeric-normal-ref.html">
|
<link rel="match" href="marker-font-variant-numeric-normal-ref.html">
|
||||||
<link rel="mismatch" href="marker-font-variant-numeric-default-ref.html">
|
|
||||||
<meta name="assert" content="Checks that the marker default 'font-variant-numeric: tabular-nums' can be overridden with 'font-variant-numeric: normal'">
|
<meta name="assert" content="Checks that the marker default 'font-variant-numeric: tabular-nums' can be overridden with 'font-variant-numeric: normal'">
|
||||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>CSS Reftest Reference</title>
|
<title>CSS Reftest Reference</title>
|
||||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
|
<link rel="mismatch" href="marker-unicode-bidi-normal-ref.html">
|
||||||
<style>
|
<style>
|
||||||
ol {
|
ol {
|
||||||
float: left;
|
float: left;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
|
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
|
||||||
<link rel="match" href="marker-unicode-bidi-default-ref.html">
|
<link rel="match" href="marker-unicode-bidi-default-ref.html">
|
||||||
<link rel="mismatch" href="marker-unicode-bidi-normal-ref.html">
|
|
||||||
<meta name="assert" content="Checks that the markers are isolated from the list items by the bidi algorithm">
|
<meta name="assert" content="Checks that the markers are isolated from the list items by the bidi algorithm">
|
||||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>CSS Reftest Reference</title>
|
<title>CSS Reftest Reference</title>
|
||||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
|
<link rel="mismatch" href="marker-unicode-bidi-default-ref.html">
|
||||||
<style>
|
<style>
|
||||||
ol {
|
ol {
|
||||||
float: left;
|
float: left;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
|
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
|
||||||
<link rel="match" href="marker-unicode-bidi-normal-ref.html">
|
<link rel="match" href="marker-unicode-bidi-normal-ref.html">
|
||||||
<link rel="mismatch" href="marker-unicode-bidi-default-ref.html">
|
|
||||||
<meta name="assert" content="Checks that the marker default 'unicode-bidi: isolate' can be overridden with 'unicode-bidi: normal'">
|
<meta name="assert" content="Checks that the marker default 'unicode-bidi: isolate' can be overridden with 'unicode-bidi: normal'">
|
||||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -9,6 +9,7 @@ div {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
font-family: Ahem;
|
font-family: Ahem;
|
||||||
width: 5.1ch;
|
width: 5.1ch;
|
||||||
|
border: 1px solid blue;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
|
@ -18,4 +19,7 @@ div {
|
||||||
<div>1234­xx</div>
|
<div>1234­xx</div>
|
||||||
<div>12345­xx</div>
|
<div>12345­xx</div>
|
||||||
<div>123456­xx</div>
|
<div>123456­xx</div>
|
||||||
|
|
||||||
|
<div style="width: 10ch"><span>ren­for­cer</span>99999</div>
|
||||||
|
<div><span>00­1</span>222</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
div {
|
div {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
font-family: Ahem;
|
font-family: Ahem;
|
||||||
|
width: 5.1ch;
|
||||||
|
border: 1px solid blue;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
|
@ -13,4 +15,7 @@ div {
|
||||||
<div>1234-<br>xx</div>
|
<div>1234-<br>xx</div>
|
||||||
<div>12345-<br>xx</div>
|
<div>12345-<br>xx</div>
|
||||||
<div>123456-<br>xx</div>
|
<div>123456-<br>xx</div>
|
||||||
|
|
||||||
|
<div style="width: 10ch">renfor-<br>cer99999</div>
|
||||||
|
<div>00-<br>1222</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<meta charset=utf-8>
|
<meta charset=utf-8>
|
||||||
<title>CSS Typed OM IDL</title>
|
<title>CSS Typed OM IDL</title>
|
||||||
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#idl-index">
|
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#idl-index">
|
||||||
|
<meta name="timeout" content="long">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="/resources/WebIDLParser.js"></script>
|
<script src="/resources/WebIDLParser.js"></script>
|
||||||
|
|
|
@ -51,7 +51,9 @@ var getWindow = mql => {
|
||||||
|
|
||||||
var waitForChangesReported = () => {
|
var waitForChangesReported = () => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
step_timeout(resolve, 75);
|
requestAnimationFrame(() => {
|
||||||
|
requestAnimationFrame(resolve);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>CSS Motion Path: offset-anchor with transform-box: fill-box on the svg g element</title>
|
||||||
|
<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-anchor-property">
|
||||||
|
<link rel="match" href="offset-anchor-transform-box-fill-box-ref.html">
|
||||||
|
<meta name="assert" content="Tests offset-anchor together with a fill-box transform-box on the <g> element">
|
||||||
|
<style>
|
||||||
|
#target {
|
||||||
|
transform-box: fill-box;
|
||||||
|
offset-anchor: 25% 25%;
|
||||||
|
offset-path: path("M75,-25v100");
|
||||||
|
offset-distance: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<svg width="400" height="400">
|
||||||
|
<rect width="100" height="100" fill="red"/>
|
||||||
|
<g id='target'>
|
||||||
|
<rect x="150" y="100" width="100" height="100" fill="green"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
|
@ -117,6 +117,38 @@ document_types().forEach(function (entry) {
|
||||||
});
|
});
|
||||||
}, 'Moving the shadow host of a custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
|
}, 'Moving the shadow host of a custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
|
||||||
|
|
||||||
|
promise_test(function () {
|
||||||
|
return getDocument().then(function (doc) {
|
||||||
|
const instance = document.createElement('my-custom-element');
|
||||||
|
const host = document.createElement('div');
|
||||||
|
const shadowRoot = host.attachShadow({mode: 'closed'});
|
||||||
|
shadowRoot.appendChild(instance);
|
||||||
|
document.body.appendChild(host);
|
||||||
|
|
||||||
|
calls = [];
|
||||||
|
doc.documentElement.appendChild(shadowRoot);
|
||||||
|
assert_array_equals(calls, ['disconnected', 'adopted', document, doc, 'connected']);
|
||||||
|
});
|
||||||
|
}, 'Moving the shadow host\'s shadow of a custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
|
||||||
|
|
||||||
|
promise_test(function () {
|
||||||
|
return getDocument().then(function (doc) {
|
||||||
|
const instance = document.createElement('my-custom-element');
|
||||||
|
const template = document.createElement('template');
|
||||||
|
const templateContent = template.content;
|
||||||
|
templateContent.appendChild(instance);
|
||||||
|
document.body.appendChild(template);
|
||||||
|
|
||||||
|
calls = [];
|
||||||
|
doc.documentElement.appendChild(templateContent);
|
||||||
|
if (doc === templateContent.ownerDocument) {
|
||||||
|
assert_array_equals(calls, ['connected']);
|
||||||
|
} else {
|
||||||
|
assert_array_equals(calls, ['adopted', templateContent.ownerDocument, doc, 'connected']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 'Moving the <template>\'s content of a custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
|
||||||
|
|
||||||
promise_test(function () {
|
promise_test(function () {
|
||||||
return getDocument().then(function (doc) {
|
return getDocument().then(function (doc) {
|
||||||
var instance = document.createElement('my-custom-element');
|
var instance = document.createElement('my-custom-element');
|
||||||
|
|
|
@ -29,8 +29,8 @@ Test authors are encouraged to use the builder API to generate the sequence of a
|
||||||
API can be accessed via the `new test_driver.Actions()` object, and actions are defined in [testdriver-actions.js](https://github.com/web-platform-tests/wpt/blob/master/resources/testdriver-actions.js)
|
API can be accessed via the `new test_driver.Actions()` object, and actions are defined in [testdriver-actions.js](https://github.com/web-platform-tests/wpt/blob/master/resources/testdriver-actions.js)
|
||||||
|
|
||||||
The `actions.send()` function causes the sequence of actions to be sent to the browser. It is based on the [WebDriver API](https://w3c.github.io/webdriver/#actions).
|
The `actions.send()` function causes the sequence of actions to be sent to the browser. It is based on the [WebDriver API](https://w3c.github.io/webdriver/#actions).
|
||||||
The action can be a keyboard action, a pointer action or a pause. It returns a `Promise` that
|
The action can be a keyboard action, a pointer action or a pause. It returns a promise that
|
||||||
resolves after the actions have been sent or rejects if an error was thrown.
|
resolves after the actions have been sent, or rejects if an error was thrown.
|
||||||
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
@ -49,7 +49,7 @@ let actions = new test_driver.Actions()
|
||||||
actions.send();
|
actions.send();
|
||||||
```
|
```
|
||||||
|
|
||||||
Calling into `send()` is going to dispatch the action sequence (via `test_driver.action_sequence`) and also returns a `Promise` which should be handled however is appropriate in the test. The other functions in the `Actions()` object are going to modify the state of the object by adding a new action in the sequence and return the same object. So the functions can be easily chained as shown in the example above. Here is a list of helper functions in the `Actions` class:
|
Calling into `send()` is going to dispatch the action sequence (via `test_driver.action_sequence`) and also returns a promise which should be handled however is appropriate in the test. The other functions in the `Actions()` object are going to modify the state of the object by adding a new action in the sequence and returning the same object. So the functions can be easily chained, as shown in the example above. Here is a list of helper functions in the `Actions` class:
|
||||||
|
|
||||||
```
|
```
|
||||||
pointerDown: Create a pointerDown event for the current default pointer source
|
pointerDown: Create a pointerDown event for the current default pointer source
|
||||||
|
@ -68,19 +68,19 @@ addKeyboard: Add a new key input source with the given name
|
||||||
### bless
|
### bless
|
||||||
|
|
||||||
Usage: `test_driver.bless(intent, action)`
|
Usage: `test_driver.bless(intent, action)`
|
||||||
* `intent`: a string describing the motivation for this invocation
|
* _intent_: a string describing the motivation for this invocation
|
||||||
* `action`: an optional function
|
* _action_: an optional function
|
||||||
|
|
||||||
This function simulates [activation][activation], allowing tests to
|
This function simulates [activation][activation], allowing tests to
|
||||||
perform privileged operations that require user interaction. For
|
perform privileged operations that require user interaction. For
|
||||||
example, sandboxed iframes with the
|
example, sandboxed iframes with
|
||||||
`allow-top-navigation-by-user-activation` may only navigate their
|
`allow-top-navigation-by-user-activation` may only navigate their
|
||||||
parent's browsing context under these circumstances. The `intent`
|
parent's browsing context under these circumstances. The _intent_
|
||||||
string is presented to human operators when the test is not run in
|
string is presented to human operators when the test is not run in
|
||||||
automation.
|
automation.
|
||||||
|
|
||||||
This method returns a promise which is resolved with the result of
|
This method returns a promise which is resolved with the result of
|
||||||
invoking the `action` function. If no such function is provided, the
|
invoking the _action_ function. If no such function is provided, the
|
||||||
promise is resolved with the value `undefined`.
|
promise is resolved with the value `undefined`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
@ -96,11 +96,11 @@ test_driver.bless('initiate media playback', function () {
|
||||||
### click
|
### click
|
||||||
|
|
||||||
Usage: `test_driver.click(element)`
|
Usage: `test_driver.click(element)`
|
||||||
* `element`: a DOM Element object
|
* _element_: a DOM Element object
|
||||||
|
|
||||||
This function causes a click to occur on the target element (an
|
This function causes a click to occur on the target element (an
|
||||||
`Element` object), potentially scrolling the document to make it
|
`Element` object), potentially scrolling the document to make it
|
||||||
possible to click it. It returns a `Promise` that resolves after the
|
possible to click it. It returns a promise that resolves after the
|
||||||
click has occurred or rejects if the element cannot be clicked (for
|
click has occurred or rejects if the element cannot be clicked (for
|
||||||
example, it is obscured by an element on top of it).
|
example, it is obscured by an element on top of it).
|
||||||
|
|
||||||
|
@ -111,16 +111,16 @@ being called and the promise settling.
|
||||||
### send_keys
|
### send_keys
|
||||||
|
|
||||||
Usage: `test_driver.send_keys(element, keys)`
|
Usage: `test_driver.send_keys(element, keys)`
|
||||||
* `element`: a DOM Element object
|
* _element_: a DOM Element object
|
||||||
* `keys`: string to send to the element
|
* _keys_: string to send to the element
|
||||||
|
|
||||||
This function causes the string `keys` to be send to the target
|
This function causes the string _keys_ to be sent to the target
|
||||||
element (an `Element` object), potentially scrolling the document to
|
element (an `Element` object), potentially scrolling the document to
|
||||||
make it possible to send keys. It returns a `Promise` that resolves
|
make it possible to send keys. It returns a promise that resolves
|
||||||
after the keys have been send or rejects if the keys cannot be sent
|
after the keys have been sent, or rejects if the keys cannot be sent
|
||||||
to the element.
|
to the element.
|
||||||
|
|
||||||
Note that if the element that's keys need to be send to does not have
|
Note that if the element that the keys need to be sent to does not have
|
||||||
a unique ID, the document must not have any DOM mutations made
|
a unique ID, the document must not have any DOM mutations made
|
||||||
between the function being called and the promise settling.
|
between the function being called and the promise settling.
|
||||||
|
|
||||||
|
@ -128,3 +128,27 @@ To send special keys, one must send the respective key's codepoint. Since this u
|
||||||
For example, to send the tab key you would send "\uE004".
|
For example, to send the tab key you would send "\uE004".
|
||||||
|
|
||||||
[activation]: https://html.spec.whatwg.org/multipage/interaction.html#activation
|
[activation]: https://html.spec.whatwg.org/multipage/interaction.html#activation
|
||||||
|
|
||||||
|
### set_permission
|
||||||
|
|
||||||
|
Usage: `test_driver.set_permission(descriptor, state, one_realm)`
|
||||||
|
* _descriptor_: a
|
||||||
|
[PermissionDescriptor](https://w3c.github.io/permissions/#dictdef-permissiondescriptor)
|
||||||
|
or derived object
|
||||||
|
* _state_: a
|
||||||
|
[PermissionState](https://w3c.github.io/permissions/#enumdef-permissionstate)
|
||||||
|
value
|
||||||
|
* _one_realm_: a boolean that indicates whether the permission settings
|
||||||
|
apply to only one realm
|
||||||
|
|
||||||
|
This function causes permission requests and queries for the status of a
|
||||||
|
certain permission type (e.g. "push", or "background-fetch") to always
|
||||||
|
return _state_. It returns a promise that resolves after the permission has
|
||||||
|
been set to be overridden with _state_.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
``` js
|
||||||
|
await test_driver.set_permission({ name: "background-fetch" }, "denied");
|
||||||
|
await test_driver.set_permission({ name: "push", userVisibleOnly: true }, "granted", true);
|
||||||
|
```
|
||||||
|
|
58
tests/wpt/web-platform-tests/dom/nodes/adoption.window.js
Normal file
58
tests/wpt/web-platform-tests/dom/nodes/adoption.window.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// Testing DocumentFragment with host separately as it has a different node document by design
|
||||||
|
test(() => {
|
||||||
|
const df = document.createElement("template").content;
|
||||||
|
const child = df.appendChild(new Text('hi'));
|
||||||
|
assert_not_equals(df.ownerDocument, document);
|
||||||
|
const nodeDocument = df.ownerDocument;
|
||||||
|
document.body.appendChild(df);
|
||||||
|
assert_equals(df.childNodes.length, 0);
|
||||||
|
assert_equals(child.ownerDocument, document);
|
||||||
|
assert_equals(df.ownerDocument, nodeDocument);
|
||||||
|
}, `appendChild() and DocumentFragment with host`);
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const df = document.createElement("template").content;
|
||||||
|
const child = df.appendChild(new Text('hi'));
|
||||||
|
const nodeDocument = df.ownerDocument;
|
||||||
|
document.adoptNode(df);
|
||||||
|
assert_equals(df.childNodes.length, 1);
|
||||||
|
assert_equals(child.ownerDocument, nodeDocument);
|
||||||
|
assert_equals(df.ownerDocument, nodeDocument);
|
||||||
|
}, `adoptNode() and DocumentFragment with host`);
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "DocumentFragment",
|
||||||
|
"creator": doc => doc.createDocumentFragment()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ShadowRoot",
|
||||||
|
"creator": doc => doc.createElementNS("http://www.w3.org/1999/xhtml", "div").attachShadow({mode: "closed"})
|
||||||
|
}
|
||||||
|
].forEach(dfTest => {
|
||||||
|
test(() => {
|
||||||
|
const doc = new Document();
|
||||||
|
const df = dfTest.creator(doc);
|
||||||
|
const child = df.appendChild(new Text('hi'));
|
||||||
|
assert_equals(df.ownerDocument, doc);
|
||||||
|
|
||||||
|
document.body.appendChild(df);
|
||||||
|
assert_equals(df.childNodes.length, 0);
|
||||||
|
assert_equals(child.ownerDocument, document);
|
||||||
|
assert_equals(df.ownerDocument, doc);
|
||||||
|
}, `appendChild() and ${dfTest.name}`);
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const doc = new Document();
|
||||||
|
const df = dfTest.creator(doc);
|
||||||
|
const child = df.appendChild(new Text('hi'));
|
||||||
|
if (dfTest.name === "ShadowRoot") {
|
||||||
|
assert_throws("HierarchyRequestError", () => document.adoptNode(df));
|
||||||
|
} else {
|
||||||
|
document.adoptNode(df);
|
||||||
|
assert_equals(df.childNodes.length, 1);
|
||||||
|
assert_equals(child.ownerDocument, document);
|
||||||
|
assert_equals(df.ownerDocument, document);
|
||||||
|
}
|
||||||
|
}, `adoptNode() and ${dfTest.name}`);
|
||||||
|
});
|
|
@ -7,28 +7,70 @@
|
||||||
// |opts.expectedBodyAsString|: the expected response body as a string. The
|
// |opts.expectedBodyAsString|: the expected response body as a string. The
|
||||||
// server is expected to echo the request body. The default is the empty string
|
// server is expected to echo the request body. The default is the empty string
|
||||||
// if the request after redirection isn't POST; otherwise it's |opts.body|.
|
// if the request after redirection isn't POST; otherwise it's |opts.body|.
|
||||||
|
// |opts.expectedRequestContentType|: the expected Content-Type of redirected
|
||||||
|
// request.
|
||||||
function redirectMethod(desc, redirectUrl, redirectLocation, redirectStatus, method, expectedMethod, opts) {
|
function redirectMethod(desc, redirectUrl, redirectLocation, redirectStatus, method, expectedMethod, opts) {
|
||||||
var url = redirectUrl;
|
let url = redirectUrl;
|
||||||
var urlParameters = "?redirect_status=" + redirectStatus;
|
let urlParameters = "?redirect_status=" + redirectStatus;
|
||||||
urlParameters += "&location=" + encodeURIComponent(redirectLocation);
|
urlParameters += "&location=" + encodeURIComponent(redirectLocation);
|
||||||
|
|
||||||
var requestInit = {"method": method, "redirect": "follow"};
|
let requestHeaders = {
|
||||||
|
"Content-Encoding": "Identity",
|
||||||
|
"Content-Language": "en-US",
|
||||||
|
"Content-Location": "foo",
|
||||||
|
};
|
||||||
|
let requestInit = {"method": method, "redirect": "follow", "headers" : requestHeaders};
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
if (opts.body)
|
if (opts.body) {
|
||||||
requestInit.body = opts.body;
|
requestInit.body = opts.body;
|
||||||
|
}
|
||||||
|
|
||||||
promise_test(function(test) {
|
promise_test(function(test) {
|
||||||
return fetch(url + urlParameters, requestInit).then(function(resp) {
|
return fetch(url + urlParameters, requestInit).then(function(resp) {
|
||||||
|
let expectedRequestContentType = "NO";
|
||||||
|
if (opts.expectedRequestContentType) {
|
||||||
|
expectedRequestContentType = opts.expectedRequestContentType;
|
||||||
|
}
|
||||||
|
|
||||||
assert_equals(resp.status, 200, "Response's status is 200");
|
assert_equals(resp.status, 200, "Response's status is 200");
|
||||||
assert_equals(resp.type, "basic", "Response's type basic");
|
assert_equals(resp.type, "basic", "Response's type basic");
|
||||||
assert_equals(resp.headers.get("x-request-method"), expectedMethod, "Request method after redirection is " + expectedMethod);
|
assert_equals(
|
||||||
|
resp.headers.get("x-request-method"),
|
||||||
|
expectedMethod,
|
||||||
|
"Request method after redirection is " + expectedMethod);
|
||||||
|
let hasRequestBodyHeader = true;
|
||||||
|
if (opts.expectedStripRequestBodyHeader) {
|
||||||
|
hasRequestBodyHeader = !opts.expectedStripRequestBodyHeader;
|
||||||
|
}
|
||||||
|
assert_equals(
|
||||||
|
resp.headers.get("x-request-content-type"),
|
||||||
|
expectedRequestContentType,
|
||||||
|
"Request Content-Type after redirection is " + expectedRequestContentType);
|
||||||
|
[
|
||||||
|
"Content-Encoding",
|
||||||
|
"Content-Language",
|
||||||
|
"Content-Location"
|
||||||
|
].forEach(header => {
|
||||||
|
let xHeader = "x-request-" + header.toLowerCase();
|
||||||
|
let expectedValue = hasRequestBodyHeader ? requestHeaders[header] : "NO";
|
||||||
|
assert_equals(
|
||||||
|
resp.headers.get(xHeader),
|
||||||
|
expectedValue,
|
||||||
|
"Request " + header + " after redirection is " + expectedValue);
|
||||||
|
});
|
||||||
assert_true(resp.redirected);
|
assert_true(resp.redirected);
|
||||||
return resp.text().then(function(text) {
|
return resp.text().then(function(text) {
|
||||||
let expectedBody = "";
|
let expectedBody = "";
|
||||||
if (expectedMethod == "POST")
|
if (expectedMethod == "POST") {
|
||||||
expectedBody = opts.expectedBodyAsString || requestInit.body;
|
expectedBody = opts.expectedBodyAsString || requestInit.body;
|
||||||
|
}
|
||||||
|
let expectedContentLength = expectedBody ? expectedBody.length.toString() : "NO";
|
||||||
assert_equals(text, expectedBody, "request body");
|
assert_equals(text, expectedBody, "request body");
|
||||||
});
|
assert_equals(
|
||||||
|
resp.headers.get("x-request-content-length"),
|
||||||
|
expectedContentLength,
|
||||||
|
"Request Content-Length after redirection is " + expectedContentLength);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, desc);
|
}, desc);
|
||||||
}
|
}
|
||||||
|
@ -49,19 +91,20 @@ const blobBody = new Blob(["it's me the blob!", " ", "and more blob!"]);
|
||||||
const blobBodyAsString = "it's me the blob! and more blob!";
|
const blobBodyAsString = "it's me the blob! and more blob!";
|
||||||
|
|
||||||
redirectMethod("Redirect 301 with GET", redirUrl, locationUrl, 301, "GET", "GET");
|
redirectMethod("Redirect 301 with GET", redirUrl, locationUrl, 301, "GET", "GET");
|
||||||
redirectMethod("Redirect 301 with POST", redirUrl, locationUrl, 301, "POST", "GET", { body: stringBody });
|
redirectMethod("Redirect 301 with POST", redirUrl, locationUrl, 301, "POST", "GET", { body: stringBody, expectedStripRequestBodyHeader: true });
|
||||||
redirectMethod("Redirect 301 with HEAD", redirUrl, locationUrl, 301, "HEAD", "HEAD");
|
redirectMethod("Redirect 301 with HEAD", redirUrl, locationUrl, 301, "HEAD", "HEAD");
|
||||||
|
|
||||||
redirectMethod("Redirect 302 with GET", redirUrl, locationUrl, 302, "GET", "GET");
|
redirectMethod("Redirect 302 with GET", redirUrl, locationUrl, 302, "GET", "GET");
|
||||||
redirectMethod("Redirect 302 with POST", redirUrl, locationUrl, 302, "POST", "GET", { body: stringBody });
|
redirectMethod("Redirect 302 with POST", redirUrl, locationUrl, 302, "POST", "GET", { body: stringBody, expectedStripRequestBodyHeader: true });
|
||||||
redirectMethod("Redirect 302 with HEAD", redirUrl, locationUrl, 302, "HEAD", "HEAD");
|
redirectMethod("Redirect 302 with HEAD", redirUrl, locationUrl, 302, "HEAD", "HEAD");
|
||||||
|
|
||||||
redirectMethod("Redirect 303 with GET", redirUrl, locationUrl, 303, "GET", "GET");
|
redirectMethod("Redirect 303 with GET", redirUrl, locationUrl, 303, "GET", "GET");
|
||||||
redirectMethod("Redirect 303 with POST", redirUrl, locationUrl, 303, "POST", "GET", { body: stringBody });
|
redirectMethod("Redirect 303 with POST", redirUrl, locationUrl, 303, "POST", "GET", { body: stringBody, expectedStripRequestBodyHeader: true });
|
||||||
redirectMethod("Redirect 303 with HEAD", redirUrl, locationUrl, 303, "HEAD", "HEAD");
|
redirectMethod("Redirect 303 with HEAD", redirUrl, locationUrl, 303, "HEAD", "HEAD");
|
||||||
|
redirectMethod("Redirect 303 with TESTING", redirUrl, locationUrl, 303, "TESTING", "GET", { expectedStripRequestBodyHeader: true });
|
||||||
|
|
||||||
redirectMethod("Redirect 307 with GET", redirUrl, locationUrl, 307, "GET", "GET");
|
redirectMethod("Redirect 307 with GET", redirUrl, locationUrl, 307, "GET", "GET");
|
||||||
redirectMethod("Redirect 307 with POST (string body)", redirUrl, locationUrl, 307, "POST", "POST", { body: stringBody });
|
redirectMethod("Redirect 307 with POST (string body)", redirUrl, locationUrl, 307, "POST", "POST", { body: stringBody , expectedRequestContentType: "text/plain;charset=UTF-8"});
|
||||||
redirectMethod("Redirect 307 with POST (blob body)", redirUrl, locationUrl, 307, "POST", "POST", { body: blobBody, expectedBodyAsString: blobBodyAsString });
|
redirectMethod("Redirect 307 with POST (blob body)", redirUrl, locationUrl, 307, "POST", "POST", { body: blobBody, expectedBodyAsString: blobBodyAsString });
|
||||||
redirectMethod("Redirect 307 with HEAD", redirUrl, locationUrl, 307, "HEAD", "HEAD");
|
redirectMethod("Redirect 307 with HEAD", redirUrl, locationUrl, 307, "HEAD", "HEAD");
|
||||||
|
|
||||||
|
|
|
@ -8,4 +8,9 @@ def main(request, response):
|
||||||
headers.append(("Access-Control-Expose-Headers", "x-request-method"))
|
headers.append(("Access-Control-Expose-Headers", "x-request-method"))
|
||||||
|
|
||||||
headers.append(("x-request-method", request.method))
|
headers.append(("x-request-method", request.method))
|
||||||
|
headers.append(("x-request-content-type", request.headers.get("Content-Type", "NO")))
|
||||||
|
headers.append(("x-request-content-length", request.headers.get("Content-Length", "NO")))
|
||||||
|
headers.append(("x-request-content-encoding", request.headers.get("Content-Encoding", "NO")))
|
||||||
|
headers.append(("x-request-content-language", request.headers.get("Content-Language", "NO")))
|
||||||
|
headers.append(("x-request-content-location", request.headers.get("Content-Location", "NO")))
|
||||||
return headers, request.body
|
return headers, request.body
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
async_test(t => {
|
||||||
|
// Setting document.domain makes this document cross-origin with that of the frame. However,
|
||||||
|
// about:blank will end up reusing the origin of this document, at which point the frame's
|
||||||
|
// document is no longer cross-origin.
|
||||||
|
const frame = document.body.appendChild(document.createElement('iframe'));
|
||||||
|
document.domain = document.domain;
|
||||||
|
frame.src = "/common/blank.html";
|
||||||
|
frame.onload = t.step_func(() => {
|
||||||
|
assert_throws("SecurityError", () => window[0].document);
|
||||||
|
frame.src = "about:blank";
|
||||||
|
frame.onload = t.step_func_done(() => {
|
||||||
|
// Ensure we can access the child browsing context after navigation to non-initial about:blank
|
||||||
|
assert_equals(window[0].document, frame.contentDocument);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, "Navigated frame to about:blank and document.domain");
|
|
@ -0,0 +1,10 @@
|
||||||
|
test(() => {
|
||||||
|
// As the initial:about frame document reuses the origin of this document, setting document.domain
|
||||||
|
// from the frame, resulting in a origin mutation, has no effect on these documents being able to
|
||||||
|
// reach each other, as they share the same "physical" origin.
|
||||||
|
document.body.appendChild(document.createElement('iframe'));
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.text = "document.domain = document.domain";
|
||||||
|
window[0].document.body.appendChild(script);
|
||||||
|
assert_equals(window[0].document.body.localName, "body");
|
||||||
|
}, "Initial about:blank frame and document.domain in the frame");
|
|
@ -0,0 +1,9 @@
|
||||||
|
test(() => {
|
||||||
|
// As the initial:about frame document reuses the origin of this document, setting document.domain
|
||||||
|
// from this document, resulting in a origin mutation, has no effect on these documents being able
|
||||||
|
// to reach each other, as they share the same "physical" origin.
|
||||||
|
document.body.appendChild(document.createElement('iframe'));
|
||||||
|
document.domain = document.domain;
|
||||||
|
// Ensure we can still access the child browsing context
|
||||||
|
assert_equals(window[0].document.body.localName, "body");
|
||||||
|
}, "Initial about:blank frame and document.domain");
|
|
@ -11,6 +11,7 @@
|
||||||
</style>
|
</style>
|
||||||
<img src="/images/green.png">
|
<img src="/images/green.png">
|
||||||
<img src="/images/green.png" width=100 height=125>
|
<img src="/images/green.png" width=100 height=125>
|
||||||
|
<img src="" width=100 height=125>
|
||||||
<script>
|
<script>
|
||||||
let t = async_test("Image width and height attributes are used to infer aspect-ratio");
|
let t = async_test("Image width and height attributes are used to infer aspect-ratio");
|
||||||
function assert_ratio(img, expected) {
|
function assert_ratio(img, expected) {
|
||||||
|
@ -46,7 +47,8 @@ t.step(function() {
|
||||||
|
|
||||||
onload = t.step_func_done(function() {
|
onload = t.step_func_done(function() {
|
||||||
let images = document.querySelectorAll("img");
|
let images = document.querySelectorAll("img");
|
||||||
assert_ratio(images[2], 1.266); // 1.266 is the original aspect ratio of blue.png
|
assert_ratio(images[3], 1.266); // 1.266 is the original aspect ratio of blue.png
|
||||||
|
assert_equals(getComputedStyle(images[2]).height, "0px"); // aspect-ratio doesn't override intrinsic size of images that don't have any src.
|
||||||
assert_ratio(images[1], 2.0); // 2.0 is the original aspect ratio of green.png
|
assert_ratio(images[1], 2.0); // 2.0 is the original aspect ratio of green.png
|
||||||
assert_ratio(images[0], 2.0); // Loaded image's aspect ratio, at least by default, overrides width / height ratio.
|
assert_ratio(images[0], 2.0); // Loaded image's aspect ratio, at least by default, overrides width / height ratio.
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,3 +37,12 @@ test(t => {
|
||||||
comment.remove();
|
comment.remove();
|
||||||
assert_not_equals(sheet, style.sheet);
|
assert_not_equals(sheet, style.sheet);
|
||||||
}, "Mutating the style element: removing a Comment node");
|
}, "Mutating the style element: removing a Comment node");
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
const style = document.body.appendChild(document.createElement("style"));
|
||||||
|
const sheet = style.sheet;
|
||||||
|
t.add_cleanup(() => style.remove());
|
||||||
|
assert_not_equals(sheet, null);
|
||||||
|
style.appendChild(new DocumentFragment());
|
||||||
|
assert_equals(sheet, style.sheet);
|
||||||
|
}, "Mutating the style element: inserting an empty DocumentFragment node");
|
||||||
|
|
|
@ -69,7 +69,10 @@
|
||||||
{conditions: {step: "", value: "-.8"}, expected: true, name: "[target] The step attribute is not set and the value attribute is a floating number"},
|
{conditions: {step: "", value: "-.8"}, expected: true, name: "[target] The step attribute is not set and the value attribute is a floating number"},
|
||||||
{conditions: {step: 2 * 1 * 1, value: ""}, expected: false, name: "[target] The value attribute is empty string"},
|
{conditions: {step: 2 * 1 * 1, value: ""}, expected: false, name: "[target] The value attribute is empty string"},
|
||||||
{conditions: {step: 2 * 1 * 1, value: "2"}, expected: false, name: "[target] The value must match the step"},
|
{conditions: {step: 2 * 1 * 1, value: "2"}, expected: false, name: "[target] The value must match the step"},
|
||||||
{conditions: {step: 2 * 1 * 1, value: "3"}, expected: true, name: "[target] The value must mismatch the step"}
|
{conditions: {step: 2 * 1 * 1, value: "3"}, expected: true, name: "[target] The value must mismatch the step"},
|
||||||
|
{conditions: {step: 0.003, value: "3.6"}, expected: false, name: "[target] No step mismatch when step is a floating number and value is its integral multiple"},
|
||||||
|
{conditions: {step: 1e-12, value: "-12345678.9"}, expected: false, name: "[target] No step mismatch when step is a floating number in exponent format and value is its integral multiple"},
|
||||||
|
{conditions: {step: 3e-15, value: "17"}, expected: true, name: "[target] Step mismatch when step is a very small floating number and value is not its integral multiple"},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
var validator = {
|
var validator = {
|
||||||
|
|
||||||
test_tooLong: function(ctl, data) {
|
test_tooLong: function(ctl, data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
test(function () {
|
test(function() {
|
||||||
self.pre_check(ctl, "tooLong");
|
self.pre_check(ctl, 'tooLong');
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
if (data.dirty)
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
self.set_dirty(ctl);
|
const {ctl, data, condStr} = val;
|
||||||
|
if (data.dirty)
|
||||||
if (data.expected)
|
self.set_dirty(ctl);
|
||||||
assert_true(ctl.validity.tooLong, "The validity.tooLong should be true.");
|
if (data.expected)
|
||||||
else
|
assert_true(
|
||||||
assert_false(ctl.validity.tooLong, "The validity.tooLong should be false.");
|
ctl.validity.tooLong,
|
||||||
|
'The validity.tooLong should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.tooLong,
|
||||||
|
'The validity.tooLong should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -19,13 +26,19 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "tooShort");
|
self.pre_check(ctl, "tooShort");
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
if (data.dirty)
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
self.set_dirty(ctl);
|
const {ctl, data, condStr} = val;
|
||||||
|
if (data.dirty)
|
||||||
if (data.expected)
|
self.set_dirty(ctl);
|
||||||
assert_true(ctl.validity.tooShort, "The validity.tooShort should be true.");
|
if (data.expected)
|
||||||
else
|
assert_true(
|
||||||
assert_false(ctl.validity.tooShort, "The validity.tooShort should be false.");
|
ctl.validity.tooShort,
|
||||||
|
'The validity.tooShort should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.tooShort,
|
||||||
|
'The validity.tooShort should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -34,11 +47,17 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "patternMismatch");
|
self.pre_check(ctl, "patternMismatch");
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
if (data.expected)
|
const {ctl, data, condStr} = val;
|
||||||
assert_true(ctl.validity.patternMismatch, "The validity.patternMismatch should be true.");
|
if (data.expected)
|
||||||
else
|
assert_true(
|
||||||
assert_false(ctl.validity.patternMismatch, "The validity.patternMismatch should be false.");
|
ctl.validity.patternMismatch,
|
||||||
|
'The validity.patternMismatch should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.patternMismatch,
|
||||||
|
'The validity.patternMismatch should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -47,10 +66,17 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "valueMissing");
|
self.pre_check(ctl, "valueMissing");
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
if (data.expected)
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
assert_true(ctl.validity.valueMissing, "The validity.valueMissing should be true.");
|
const {ctl, data, condStr} = val;
|
||||||
else
|
if (data.expected)
|
||||||
assert_false(ctl.validity.valueMissing, "The validity.valueMissing should be false.");
|
assert_true(
|
||||||
|
ctl.validity.valueMissing,
|
||||||
|
'The validity.valueMissing should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.valueMissing,
|
||||||
|
'The validity.valueMissing should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -59,11 +85,17 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "typeMismatch");
|
self.pre_check(ctl, "typeMismatch");
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
if (data.expected)
|
const {ctl, data, condStr} = val;
|
||||||
assert_true(ctl.validity.typeMismatch, "The validity.typeMismatch should be true.");
|
if (data.expected)
|
||||||
else
|
assert_true(
|
||||||
assert_false(ctl.validity.typeMismatch, "The validity.typeMismatch should be false.");
|
ctl.validity.typeMismatch,
|
||||||
|
'The validity.typeMismatch should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.typeMismatch,
|
||||||
|
'The validity.typeMismatch should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -72,11 +104,17 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "rangeOverflow");
|
self.pre_check(ctl, "rangeOverflow");
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
if (data.expected)
|
const {ctl, data, condStr} = val;
|
||||||
assert_true(ctl.validity.rangeOverflow, "The validity.rangeOverflow should be true.");
|
if (data.expected)
|
||||||
else
|
assert_true(
|
||||||
assert_false(ctl.validity.rangeOverflow, "The validity.rangeOverflow should be false.");
|
ctl.validity.rangeOverflow,
|
||||||
|
'The validity.rangeOverflow should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.rangeOverflow,
|
||||||
|
'The validity.rangeOverflow should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -85,10 +123,17 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "rangeUnderflow");
|
self.pre_check(ctl, "rangeUnderflow");
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
if (data.expected)
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
assert_true(ctl.validity.rangeUnderflow, "The validity.rangeUnderflow should be true.");
|
const {ctl, data, condStr} = val;
|
||||||
else
|
if (data.expected)
|
||||||
assert_false(ctl.validity.rangeUnderflow, "The validity.rangeUnderflow should be false.");
|
assert_true(
|
||||||
|
ctl.validity.rangeUnderflow,
|
||||||
|
'The validity.rangeUnderflow should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.rangeUnderflow,
|
||||||
|
'The validity.rangeUnderflow should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -97,11 +142,17 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "stepMismatch");
|
self.pre_check(ctl, "stepMismatch");
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
if (data.expected)
|
const {ctl, data, condStr} = val;
|
||||||
assert_true(ctl.validity.stepMismatch, "The validity.stepMismatch should be true.");
|
if (data.expected)
|
||||||
else
|
assert_true(
|
||||||
assert_false(ctl.validity.stepMismatch, "The validity.stepMismatch should be false.");
|
ctl.validity.stepMismatch,
|
||||||
|
'The validity.stepMismatch should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.stepMismatch,
|
||||||
|
'The validity.stepMismatch should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -110,11 +161,17 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "badInput");
|
self.pre_check(ctl, "badInput");
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
if (data.expected)
|
const {ctl, data, condStr} = val;
|
||||||
assert_true(ctl.validity.badInput, "The validity.badInput should be true.");
|
if (data.expected)
|
||||||
else
|
assert_true(
|
||||||
assert_false(ctl.validity.badInput, "The validity.badInput should be false.");
|
ctl.validity.badInput,
|
||||||
|
'The validity.badInput should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.badInput,
|
||||||
|
'The validity.badInput should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -123,29 +180,45 @@ var validator = {
|
||||||
test(function () {
|
test(function () {
|
||||||
self.pre_check(ctl, "customError");
|
self.pre_check(ctl, "customError");
|
||||||
ctl.setCustomValidity(data.conditions.message);
|
ctl.setCustomValidity(data.conditions.message);
|
||||||
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
if (data.expected) {
|
const {ctl, data, condStr} = val;
|
||||||
assert_true(ctl.validity.customError, "The validity.customError attribute should be true.");
|
if (data.expected) {
|
||||||
assert_equals(ctl.validationMessage, data.conditions.message,
|
assert_true(
|
||||||
"The validationMessage attribute should be '" + data.conditions.message + "'.");
|
ctl.validity.customError,
|
||||||
} else {
|
'The validity.customError attribute should be true' + condStr);
|
||||||
assert_false(ctl.validity.customError, "The validity.customError attribute should be false.");
|
assert_equals(
|
||||||
assert_equals(ctl.validationMessage, "", "The validationMessage attribute must be empty.");
|
ctl.validationMessage, data.conditions.message,
|
||||||
}
|
'The validationMessage attribute should be \'' +
|
||||||
|
data.conditions.message + '\'' + condStr);
|
||||||
|
} else {
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.customError,
|
||||||
|
'The validity.customError attribute should be false' + condStr);
|
||||||
|
assert_equals(
|
||||||
|
ctl.validationMessage, '',
|
||||||
|
'The validationMessage attribute must be empty' + condStr);
|
||||||
|
}
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
test_isValid: function (ctl, data) {
|
test_isValid: function(ctl, data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
test(function () {
|
test(function () {
|
||||||
self.set_conditions(ctl, data.conditions);
|
self.set_conditions(ctl, data.conditions);
|
||||||
if (data.dirty)
|
self.iterate_over(ctl, data).forEach(function(val) {
|
||||||
self.set_dirty(ctl);
|
const {ctl, data, condStr} = val;
|
||||||
|
if (data.dirty)
|
||||||
if (data.expected)
|
self.set_dirty(ctl);
|
||||||
assert_true(ctl.validity.valid, "The validity.valid should be true.");
|
if (data.expected)
|
||||||
else
|
assert_true(
|
||||||
assert_false(ctl.validity.valid, "The validity.valid should be false.");
|
ctl.validity.valid,
|
||||||
|
'The validity.valid should be true' + condStr);
|
||||||
|
else
|
||||||
|
assert_false(
|
||||||
|
ctl.validity.valid,
|
||||||
|
'The validity.valid should be false' + condStr);
|
||||||
|
});
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -166,7 +239,7 @@ var validator = {
|
||||||
}, data.name);
|
}, data.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
test_checkValidity: function (ctl, data) {
|
test_checkValidity: function(ctl, data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
test(function () {
|
test(function () {
|
||||||
var eventFired = false;
|
var eventFired = false;
|
||||||
|
@ -210,7 +283,7 @@ var validator = {
|
||||||
}, data.name + " (in a form)");
|
}, data.name + " (in a form)");
|
||||||
},
|
},
|
||||||
|
|
||||||
test_reportValidity: function (ctl, data) {
|
test_reportValidity: function(ctl, data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
test(function () {
|
test(function () {
|
||||||
var eventFired = false;
|
var eventFired = false;
|
||||||
|
@ -255,13 +328,13 @@ var validator = {
|
||||||
}, data.name + " (in a form)");
|
}, data.name + " (in a form)");
|
||||||
},
|
},
|
||||||
|
|
||||||
test_support_type: function (ctl, typ, testName) {
|
test_support_type: function(ctl, typ, testName) {
|
||||||
test(function () {
|
test(function () {
|
||||||
assert_equals(ctl.type, typ, "The " + typ + " type should be supported.");
|
assert_equals(ctl.type, typ, "The " + typ + " type should be supported.");
|
||||||
}, testName);
|
}, testName);
|
||||||
},
|
},
|
||||||
|
|
||||||
set_conditions: function (ctl, obj) {
|
set_conditions: function(ctl, obj) {
|
||||||
[
|
[
|
||||||
"checked",
|
"checked",
|
||||||
"disabled",
|
"disabled",
|
||||||
|
@ -322,7 +395,28 @@ var validator = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
run_test: function (testee, method) {
|
iterate_over: function(ctl, data) {
|
||||||
|
// Iterate over normal, disabled, readonly, and both.
|
||||||
|
var ctlDisabled = ctl.cloneNode(true);
|
||||||
|
ctlDisabled.disabled = true;
|
||||||
|
var ctlReadonly = ctl.cloneNode(true);
|
||||||
|
ctlReadonly.readonly = true;
|
||||||
|
var ctlBoth = ctl.cloneNode(true);
|
||||||
|
ctlBoth.disabled = true;
|
||||||
|
ctlBoth.readonly = true;
|
||||||
|
return [
|
||||||
|
{ctl: ctl, data: data, condStr: '.'},
|
||||||
|
{ctl: ctlDisabled, data: data, condStr: ', when control is disabled.'},
|
||||||
|
{ctl: ctlReadonly, data: data, condStr: ', when control is readonly.'},
|
||||||
|
{
|
||||||
|
ctl: ctlBoth,
|
||||||
|
data: data,
|
||||||
|
condStr: ', when control is disabled & readonly.'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
run_test: function(testee, method) {
|
||||||
var testMethod = "test_" + method;
|
var testMethod = "test_" + method;
|
||||||
if (typeof this[testMethod] !== "function") {
|
if (typeof this[testMethod] !== "function") {
|
||||||
return false;
|
return false;
|
||||||
|
@ -363,7 +457,7 @@ var validator = {
|
||||||
prefix = "[" + testee[i].tag + "] ";
|
prefix = "[" + testee[i].tag + "] ";
|
||||||
|
|
||||||
if (testElements[i].tag === "select") {
|
if (testElements[i].tag === "select") {
|
||||||
ele.add(new Option("test1", ""));
|
ele.add(new Option('test1', '')); // Placeholder
|
||||||
ele.add(new Option("test2", 1));
|
ele.add(new Option("test2", 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title></title>
|
|
||||||
</head>
|
|
||||||
<meta name="author" title="Takayoshi Kochi" href="mailto:kochi@chromium.org">
|
<meta name="author" title="Takayoshi Kochi" href="mailto:kochi@chromium.org">
|
||||||
<meta name="assert" title="host-including inclusive ancestor should be checked for template content">
|
|
||||||
<link rel="help" href="https://dom.spec.whatwg.org/#concept-tree-host-including-inclusive-ancestor">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
</head>
|
<div id=log></div>
|
||||||
<body>
|
|
||||||
<div id="parent">
|
<div id="parent">
|
||||||
<template id="tmpl"><span>Happy Templating!</span></template>
|
<template id="tmpl"><span>Happy Templating!</span></template>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
|
||||||
<script>
|
<script>
|
||||||
test(() => {
|
test(() => {
|
||||||
var parent = document.getElementById('parent');
|
var parent = document.getElementById('parent');
|
||||||
|
@ -53,12 +45,11 @@ test(() => {
|
||||||
assert_not_equals(new_doc, tmpl_doc);
|
assert_not_equals(new_doc, tmpl_doc);
|
||||||
|
|
||||||
// Try moving tmpl.content to new_doc and check the results.
|
// Try moving tmpl.content to new_doc and check the results.
|
||||||
var new_node = new_doc.adoptNode(tmpl.content);
|
const tmplContentNodeDocument = tmpl.content.ownerDocument;
|
||||||
assert_equals(new_node.ownerDocument, new_doc);
|
const tmplContentAdoptResult = new_doc.adoptNode(tmpl.content);
|
||||||
|
assert_equals(tmpl.content, tmplContentAdoptResult);
|
||||||
assert_equals(tmpl.ownerDocument, document);
|
assert_equals(tmpl.ownerDocument, document);
|
||||||
assert_equals(tmpl.content.ownerDocument, new_doc);
|
assert_equals(tmpl.content.ownerDocument, tmplContentNodeDocument);
|
||||||
assert_not_equals(tmpl.content.ownerDocument, tmpl_doc);
|
|
||||||
assert_not_equals(tmpl.content.ownerDocument, document);
|
|
||||||
|
|
||||||
// Hierarchy checks at various combinations.
|
// Hierarchy checks at various combinations.
|
||||||
assert_throws('HierarchyRequestError', () => {
|
assert_throws('HierarchyRequestError', () => {
|
||||||
|
@ -79,7 +70,7 @@ test(() => {
|
||||||
assert_equals(tmpl.content.firstChild, span,
|
assert_equals(tmpl.content.firstChild, span,
|
||||||
'<span> should be kept until it is removed, even after ' +
|
'<span> should be kept until it is removed, even after ' +
|
||||||
'adopted to another document.');
|
'adopted to another document.');
|
||||||
new_doc.body.appendChild(new_node);
|
new_doc.body.appendChild(tmpl.content);
|
||||||
assert_equals(tmpl.content.firstChild, null,
|
assert_equals(tmpl.content.firstChild, null,
|
||||||
'<span> should be removed from template content.');
|
'<span> should be removed from template content.');
|
||||||
assert_equals(tmpl_content_reference, tmpl.content,
|
assert_equals(tmpl_content_reference, tmpl.content,
|
||||||
|
@ -88,4 +79,3 @@ test(() => {
|
||||||
}, 'Template content should throw exception when its ancestor in ' +
|
}, 'Template content should throw exception when its ancestor in ' +
|
||||||
'a different document but connected via host is being append.');
|
'a different document but connected via host is being append.');
|
||||||
</script>
|
</script>
|
||||||
</html>
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
[multiTouchPointsReleaseFirstPoint.html]
|
||||||
|
expected:
|
||||||
|
if product == "firefox" or product == "safari": ERROR
|
||||||
|
[TestDriver actions: two touch points with one moving one pause]
|
||||||
|
expected:
|
||||||
|
if product == "chrome": FAIL
|
|
@ -0,0 +1,6 @@
|
||||||
|
[multiTouchPointsReleaseSecondPoint.html]
|
||||||
|
expected:
|
||||||
|
if product == "firefox" or product == "safari": ERROR
|
||||||
|
[TestDriver actions: two touch points with one moving one pause]
|
||||||
|
expected:
|
||||||
|
if product == "chrome": FAIL
|
|
@ -1,4 +1,4 @@
|
||||||
[generate_test_report.html]
|
[generate_test_report.html]
|
||||||
expected:
|
[TestDriver generate_test_report method]
|
||||||
if product == "firefox": ERROR
|
expected:
|
||||||
if product == "safari" or product == "epiphany" or product == "webkit": ERROR
|
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": FAIL
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
[set_permission.https.html]
|
[set_permission.https.html]
|
||||||
expected:
|
[Grant Permission for one realm]
|
||||||
if product != "chrome": ERROR
|
expected:
|
||||||
|
if product != "chrome": FAIL
|
||||||
|
|
||||||
|
[Deny Permission, omit one realm]
|
||||||
|
expected:
|
||||||
|
if product != "chrome": FAIL
|
||||||
|
|
|
@ -1,3 +1,28 @@
|
||||||
[virtual_authenticator.html]
|
[virtual_authenticator.html]
|
||||||
expected:
|
[Can create an authenticator]
|
||||||
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": ERROR
|
expected:
|
||||||
|
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": FAIL
|
||||||
|
|
||||||
|
[Can add a credential]
|
||||||
|
expected:
|
||||||
|
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": FAIL
|
||||||
|
|
||||||
|
[Can get the credentials]
|
||||||
|
expected:
|
||||||
|
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": FAIL
|
||||||
|
|
||||||
|
[Can remove a credential]
|
||||||
|
expected:
|
||||||
|
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": FAIL
|
||||||
|
|
||||||
|
[Can remove all credentials]
|
||||||
|
expected:
|
||||||
|
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": FAIL
|
||||||
|
|
||||||
|
[Can set user verified]
|
||||||
|
expected:
|
||||||
|
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": FAIL
|
||||||
|
|
||||||
|
[Can remove a virtual authenticator]
|
||||||
|
expected:
|
||||||
|
if product == "firefox" or product == "safari" or product == "epiphany" or product == "webkit": FAIL
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>TestDriver actions: two touch points with one moving one pause</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/testdriver.js"></script>
|
||||||
|
<script src="/resources/testdriver-actions.js"></script>
|
||||||
|
<script src="/resources/testdriver-vendor.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div#test1{
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="test1">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let event_type = [];
|
||||||
|
let event_id = [];
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
let test1 = document.getElementById("test1");
|
||||||
|
document.getElementById("test1").addEventListener("pointerdown",
|
||||||
|
e => {event_type.push(e.type); event_id.push(e.pointerId);});
|
||||||
|
document.getElementById("test1").addEventListener("pointerup",
|
||||||
|
e => {event_type.push(e.type); event_id.push(e.pointerId);});
|
||||||
|
document.getElementById("test1").addEventListener("pointermove",
|
||||||
|
e => {event_type.push(e.type); event_id.push(e.pointerId);});
|
||||||
|
|
||||||
|
let actions = new test_driver.Actions()
|
||||||
|
.addPointer("touchPointer1", "touch")
|
||||||
|
.addPointer("touchPointer2", "touch")
|
||||||
|
.pointerMove(0, 0, {origin: test1, sourceName: "touchPointer1"})
|
||||||
|
.pointerMove(10, 0, {origin: test1, sourceName: "touchPointer2"})
|
||||||
|
.pointerDown({sourceName: "touchPointer1"})
|
||||||
|
.pointerDown({sourceName: "touchPointer2"})
|
||||||
|
.pointerUp({sourceName: "touchPointer1"})
|
||||||
|
.pointerMove(10, 10, {origin: test1, sourceName: "touchPointer2"})
|
||||||
|
.pointerUp({sourceName: "touchPointer2"});
|
||||||
|
|
||||||
|
actions.send()
|
||||||
|
.then(t.step_func_done(() => {
|
||||||
|
assert_array_equals(event_type, ["pointerdown", "pointerdown", "pointerup", "pointermove", "pointerup"]);
|
||||||
|
assert_array_equals(event_id, [2, 3, 2, 3, 3]);
|
||||||
|
}))
|
||||||
|
.catch(e => t.step_func(() => assert_unreached("Actions sequence failed " + e)));
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,56 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>TestDriver actions: two touch points with one moving one pause</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/testdriver.js"></script>
|
||||||
|
<script src="/resources/testdriver-actions.js"></script>
|
||||||
|
<script src="/resources/testdriver-vendor.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div#test1{
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="test1">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let event_type = [];
|
||||||
|
let event_id = [];
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
let test1 = document.getElementById("test1");
|
||||||
|
document.getElementById("test1").addEventListener("pointerdown",
|
||||||
|
e => {event_type.push(e.type); event_id.push(e.pointerId);});
|
||||||
|
document.getElementById("test1").addEventListener("pointerup",
|
||||||
|
e => {event_type.push(e.type); event_id.push(e.pointerId);});
|
||||||
|
document.getElementById("test1").addEventListener("pointermove",
|
||||||
|
e => {event_type.push(e.type); event_id.push(e.pointerId);});
|
||||||
|
|
||||||
|
let actions = new test_driver.Actions()
|
||||||
|
.addPointer("touchPointer1", "touch")
|
||||||
|
.addPointer("touchPointer2", "touch")
|
||||||
|
.pointerMove(0, 0, {origin: test1, sourceName: "touchPointer1"})
|
||||||
|
.pointerMove(10, 0, {origin: test1, sourceName: "touchPointer2"})
|
||||||
|
.pointerDown({sourceName: "touchPointer1"})
|
||||||
|
.pointerDown({sourceName: "touchPointer2"})
|
||||||
|
.pointerMove(10, 10, {origin: test1, sourceName: "touchPointer1"})
|
||||||
|
.pointerUp({sourceName: "touchPointer2"})
|
||||||
|
.pointerUp({sourceName: "touchPointer1"});
|
||||||
|
|
||||||
|
actions.send()
|
||||||
|
.then(t.step_func_done(() => {
|
||||||
|
assert_array_equals(event_type, ["pointerdown", "pointerdown", "pointermove", "pointerup", "pointerup"]);
|
||||||
|
assert_array_equals(event_id, [2, 3, 2, 3, 2]);
|
||||||
|
}))
|
||||||
|
.catch(e => t.step_func(() => assert_unreached("Actions sequence failed " + e)));
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -24,7 +24,7 @@ let credential = {
|
||||||
isResidentCredential: false,
|
isResidentCredential: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let authenticator_id;
|
let authenticator_id = null;
|
||||||
|
|
||||||
promise_test(async t => {
|
promise_test(async t => {
|
||||||
authenticator_id = await test_driver.add_virtual_authenticator({
|
authenticator_id = await test_driver.add_virtual_authenticator({
|
||||||
|
|
|
@ -19,6 +19,12 @@ interface CookieStore : EventTarget {
|
||||||
Promise<void> delete(USVString name);
|
Promise<void> delete(USVString name);
|
||||||
Promise<void> delete(CookieStoreDeleteOptions options);
|
Promise<void> delete(CookieStoreDeleteOptions options);
|
||||||
|
|
||||||
|
[Exposed=ServiceWorker]
|
||||||
|
Promise<void> subscribeToChanges(sequence<CookieStoreGetOptions> subscriptions);
|
||||||
|
|
||||||
|
[Exposed=ServiceWorker]
|
||||||
|
Promise<sequence<CookieStoreGetOptions>> getChangeSubscriptions();
|
||||||
|
|
||||||
[Exposed=Window]
|
[Exposed=Window]
|
||||||
attribute EventHandler onchange;
|
attribute EventHandler onchange;
|
||||||
};
|
};
|
||||||
|
@ -71,7 +77,8 @@ dictionary CookieListItem {
|
||||||
|
|
||||||
typedef sequence<CookieListItem> CookieList;
|
typedef sequence<CookieListItem> CookieList;
|
||||||
|
|
||||||
[Exposed=Window, SecureContext]
|
[Exposed=Window,
|
||||||
|
SecureContext]
|
||||||
interface CookieChangeEvent : Event {
|
interface CookieChangeEvent : Event {
|
||||||
constructor(DOMString type, optional CookieChangeEventInit eventInitDict = {});
|
constructor(DOMString type, optional CookieChangeEventInit eventInitDict = {});
|
||||||
readonly attribute CookieList changed;
|
readonly attribute CookieList changed;
|
||||||
|
@ -83,8 +90,8 @@ dictionary CookieChangeEventInit : EventInit {
|
||||||
CookieList deleted;
|
CookieList deleted;
|
||||||
};
|
};
|
||||||
|
|
||||||
[Exposed=ServiceWorker]
|
[Exposed=ServiceWorker
|
||||||
interface ExtendableCookieChangeEvent : ExtendableEvent {
|
] interface ExtendableCookieChangeEvent : ExtendableEvent {
|
||||||
constructor(DOMString type, optional ExtendableCookieChangeEventInit eventInitDict = {});
|
constructor(DOMString type, optional ExtendableCookieChangeEventInit eventInitDict = {});
|
||||||
readonly attribute CookieList changed;
|
readonly attribute CookieList changed;
|
||||||
readonly attribute CookieList deleted;
|
readonly attribute CookieList deleted;
|
||||||
|
@ -95,13 +102,6 @@ dictionary ExtendableCookieChangeEventInit : ExtendableEventInit {
|
||||||
CookieList deleted;
|
CookieList deleted;
|
||||||
};
|
};
|
||||||
|
|
||||||
[Exposed=(ServiceWorker,Window), SecureContext]
|
|
||||||
interface CookieStoreManager {
|
|
||||||
Promise<void> subscribe(sequence<CookieStoreGetOptions> subscriptions);
|
|
||||||
Promise<sequence<CookieStoreGetOptions>> getSubscriptions();
|
|
||||||
Promise<void> unsubscribe(sequence<CookieStoreGetOptions> subscriptions);
|
|
||||||
};
|
|
||||||
|
|
||||||
[SecureContext]
|
[SecureContext]
|
||||||
partial interface Window {
|
partial interface Window {
|
||||||
[Replaceable, SameObject] readonly attribute CookieStore cookieStore;
|
[Replaceable, SameObject] readonly attribute CookieStore cookieStore;
|
||||||
|
@ -109,10 +109,6 @@ partial interface Window {
|
||||||
|
|
||||||
partial interface ServiceWorkerGlobalScope {
|
partial interface ServiceWorkerGlobalScope {
|
||||||
[Replaceable, SameObject] readonly attribute CookieStore cookieStore;
|
[Replaceable, SameObject] readonly attribute CookieStore cookieStore;
|
||||||
|
|
||||||
attribute EventHandler oncookiechange;
|
attribute EventHandler oncookiechange;
|
||||||
};
|
};
|
||||||
|
|
||||||
[Exposed=(ServiceWorker,Window), SecureContext]
|
|
||||||
partial interface ServiceWorkerRegistration {
|
|
||||||
readonly attribute CookieStoreManager cookies;
|
|
||||||
};
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// (https://github.com/tidoust/reffy-reports)
|
// (https://github.com/tidoust/reffy-reports)
|
||||||
// Source: Feature Policy (https://w3c.github.io/webappsec-feature-policy/)
|
// Source: Feature Policy (https://w3c.github.io/webappsec-feature-policy/)
|
||||||
|
|
||||||
|
[Exposed=Window]
|
||||||
interface FeaturePolicy {
|
interface FeaturePolicy {
|
||||||
boolean allowsFeature(DOMString feature, optional DOMString origin);
|
boolean allowsFeature(DOMString feature, optional DOMString origin);
|
||||||
sequence<DOMString> features();
|
sequence<DOMString> features();
|
||||||
|
@ -17,6 +18,7 @@ partial interface Document {
|
||||||
partial interface HTMLIFrameElement {
|
partial interface HTMLIFrameElement {
|
||||||
[SameObject] readonly attribute FeaturePolicy featurePolicy;
|
[SameObject] readonly attribute FeaturePolicy featurePolicy;
|
||||||
};
|
};
|
||||||
|
|
||||||
[Exposed=Window]
|
[Exposed=Window]
|
||||||
interface FeaturePolicyViolationReportBody : ReportBody {
|
interface FeaturePolicyViolationReportBody : ReportBody {
|
||||||
readonly attribute DOMString featureId;
|
readonly attribute DOMString featureId;
|
||||||
|
|
|
@ -8,7 +8,6 @@ dictionary RTCConfiguration {
|
||||||
RTCIceTransportPolicy iceTransportPolicy;
|
RTCIceTransportPolicy iceTransportPolicy;
|
||||||
RTCBundlePolicy bundlePolicy;
|
RTCBundlePolicy bundlePolicy;
|
||||||
RTCRtcpMuxPolicy rtcpMuxPolicy;
|
RTCRtcpMuxPolicy rtcpMuxPolicy;
|
||||||
DOMString peerIdentity;
|
|
||||||
sequence<RTCCertificate> certificates;
|
sequence<RTCCertificate> certificates;
|
||||||
[EnforceRange] octet iceCandidatePoolSize = 0;
|
[EnforceRange] octet iceCandidatePoolSize = 0;
|
||||||
};
|
};
|
||||||
|
@ -296,11 +295,9 @@ dictionary RTCRtpParameters {
|
||||||
dictionary RTCRtpSendParameters : RTCRtpParameters {
|
dictionary RTCRtpSendParameters : RTCRtpParameters {
|
||||||
required DOMString transactionId;
|
required DOMString transactionId;
|
||||||
required sequence<RTCRtpEncodingParameters> encodings;
|
required sequence<RTCRtpEncodingParameters> encodings;
|
||||||
RTCDegradationPreference degradationPreference = "balanced";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary RTCRtpReceiveParameters : RTCRtpParameters {
|
dictionary RTCRtpReceiveParameters : RTCRtpParameters {
|
||||||
required sequence<RTCRtpDecodingParameters> encodings;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary RTCRtpCodingParameters {
|
dictionary RTCRtpCodingParameters {
|
||||||
|
@ -315,12 +312,6 @@ dictionary RTCRtpEncodingParameters : RTCRtpCodingParameters {
|
||||||
double scaleResolutionDownBy;
|
double scaleResolutionDownBy;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RTCDegradationPreference {
|
|
||||||
"maintain-framerate",
|
|
||||||
"maintain-resolution",
|
|
||||||
"balanced"
|
|
||||||
};
|
|
||||||
|
|
||||||
dictionary RTCRtcpParameters {
|
dictionary RTCRtcpParameters {
|
||||||
DOMString cname;
|
DOMString cname;
|
||||||
boolean reducedSize;
|
boolean reducedSize;
|
||||||
|
@ -615,14 +606,6 @@ enum RTCErrorDetailType {
|
||||||
"data-channel-failure",
|
"data-channel-failure",
|
||||||
"dtls-failure",
|
"dtls-failure",
|
||||||
"fingerprint-failure",
|
"fingerprint-failure",
|
||||||
"idp-bad-script-failure",
|
|
||||||
"idp-execution-failure",
|
|
||||||
"idp-load-failure",
|
|
||||||
"idp-need-login",
|
|
||||||
"idp-timeout",
|
|
||||||
"idp-tls-failure",
|
|
||||||
"idp-token-expired",
|
|
||||||
"idp-token-invalid",
|
|
||||||
"sctp-failure",
|
"sctp-failure",
|
||||||
"sdp-syntax-error",
|
"sdp-syntax-error",
|
||||||
"hardware-encoder-not-available",
|
"hardware-encoder-not-available",
|
||||||
|
|
|
@ -193,7 +193,7 @@ interface XRWebGLLayer {
|
||||||
readonly attribute boolean antialias;
|
readonly attribute boolean antialias;
|
||||||
readonly attribute boolean ignoreDepthValues;
|
readonly attribute boolean ignoreDepthValues;
|
||||||
|
|
||||||
[SameObject] readonly attribute WebGLFramebuffer framebuffer;
|
[SameObject] readonly attribute WebGLFramebuffer? framebuffer;
|
||||||
readonly attribute unsigned long framebufferWidth;
|
readonly attribute unsigned long framebufferWidth;
|
||||||
readonly attribute unsigned long framebufferHeight;
|
readonly attribute unsigned long framebufferHeight;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<link rel="help" href="https://github.com/scott-little/lazyload">
|
<link rel="help" href="https://github.com/scott-little/lazyload">
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="common.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
@ -24,12 +25,16 @@ Marked as tentative until https://github.com/whatwg/html/pull/3752 is landed.
|
||||||
|
|
||||||
window.addEventListener("load", t.step_func(function() {
|
window.addEventListener("load", t.step_func(function() {
|
||||||
assert_true(has_in_viewport_loaded, "The in_viewport element should have loaded before window.load().");
|
assert_true(has_in_viewport_loaded, "The in_viewport element should have loaded before window.load().");
|
||||||
|
assert_true(document.getElementById("in_viewport").complete);
|
||||||
assert_false(has_window_loaded, "The window.load() event should only fire once.");
|
assert_false(has_window_loaded, "The window.load() event should only fire once.");
|
||||||
has_window_loaded = true;
|
has_window_loaded = true;
|
||||||
document.getElementById("below_viewport").scrollIntoView();
|
document.getElementById("below_viewport").scrollIntoView();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const below_viewport_img_onload = t.step_func_done(function() {
|
const below_viewport_img_onload = t.step_func_done(function() {
|
||||||
|
assert_true(is_image_fully_loaded(
|
||||||
|
document.getElementById("below_viewport"),
|
||||||
|
document.getElementById("in_viewport")));
|
||||||
assert_true(has_window_loaded, "The window.load() event should have fired before below_viewport loaded.");
|
assert_true(has_window_loaded, "The window.load() event should have fired before below_viewport loaded.");
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -8,7 +8,7 @@ async_test(t => {
|
||||||
return;
|
return;
|
||||||
assert_equals(entry.entryType, 'longtask');
|
assert_equals(entry.entryType, 'longtask');
|
||||||
assert_equals(entry.name, 'self');
|
assert_equals(entry.name, 'self');
|
||||||
assert_greater_than(longtask.duration, 50);
|
assert_greater_than(entry.duration, 50);
|
||||||
longtaskObserved = true;
|
longtaskObserved = true;
|
||||||
});
|
});
|
||||||
assert_true(longtaskObserved, 'Did not observe buffered longtask.');
|
assert_true(longtaskObserved, 'Did not observe buffered longtask.');
|
||||||
|
|
|
@ -70,49 +70,6 @@
|
||||||
test.done();
|
test.done();
|
||||||
});
|
});
|
||||||
}, "Test HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API");
|
}, "Test HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API");
|
||||||
|
|
||||||
|
|
||||||
mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
|
|
||||||
{
|
|
||||||
var previousQuality = mediaElement.getVideoPlaybackQuality();
|
|
||||||
var timeUpdateCount = 0;
|
|
||||||
var startTime = 0;
|
|
||||||
mediaElement.addEventListener("timeupdate", test.step_func(function (e)
|
|
||||||
{
|
|
||||||
var videoElement = e.target;
|
|
||||||
var newQuality = videoElement.getVideoPlaybackQuality();
|
|
||||||
var now = window.performance.now();
|
|
||||||
|
|
||||||
assert_greater_than_equal(newQuality.totalFrameDelay, 0, "totalFrameDelay >= 0");
|
|
||||||
assert_greater_than_equal(newQuality.totalFrameDelay, previousQuality.totalFrameDelay,
|
|
||||||
"totalFrameDelay increases monotonically");
|
|
||||||
assert_less_than(newQuality.totalFrameDelay, (now - startTime) / 1000,
|
|
||||||
"totalFrameDelay does not exceed the time elapsed since playback started");
|
|
||||||
|
|
||||||
previousQuality = newQuality;
|
|
||||||
timeUpdateCount++;
|
|
||||||
}));
|
|
||||||
|
|
||||||
mediaElement.addEventListener('error', test.unreached_func("Unexpected event 'error'"));
|
|
||||||
|
|
||||||
sourceBuffer.appendBuffer(mediaData);
|
|
||||||
test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer');
|
|
||||||
test.waitForExpectedEvents(function()
|
|
||||||
{
|
|
||||||
assert_false(sourceBuffer.updating, "updating");
|
|
||||||
mediaSource.endOfStream();
|
|
||||||
assert_less_than(mediaSource.duration, 10, "duration");
|
|
||||||
startTime = window.performance.now();
|
|
||||||
mediaElement.play().catch(test.unreached_func("Unexpected promise rejection"));
|
|
||||||
test.expectEvent(mediaElement, 'ended', 'mediaElement');
|
|
||||||
});
|
|
||||||
|
|
||||||
test.waitForExpectedEvents(function()
|
|
||||||
{
|
|
||||||
assert_greater_than(timeUpdateCount, 2, "timeUpdateCount");
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
}, "Test the totalFrameDelay attribute of HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API");
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -19,24 +19,24 @@
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
await runTestInPortal(portalSrc, 'testIFrameSrcInPortal');
|
await runTestInPortal(portalSrc, 'testIFrameSrcInPortal');
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
}, 'Setting iframe src navigates independently in a portal');
|
}, 'Setting iframe src navigates independently with replacement in a portal');
|
||||||
|
|
||||||
promise_test(async () => {
|
promise_test(async () => {
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
await runTestInPortal(portalSrc, 'testCrossSiteIFrameSrcInPortal');
|
await runTestInPortal(portalSrc, 'testCrossSiteIFrameSrcInPortal');
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
}, 'Setting cross site iframe src navigates independently in a portal');
|
}, 'Setting cross site iframe src navigates independently with replacement in a portal');
|
||||||
|
|
||||||
promise_test(async () => {
|
promise_test(async () => {
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
await runTestInPortal(portalSrc, 'testIFrameNavInPortal');
|
await runTestInPortal(portalSrc, 'testIFrameNavInPortal');
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
}, 'iframe navigates itself independently in a portal');
|
}, 'iframe navigates itself independently with replacement in a portal');
|
||||||
|
|
||||||
promise_test(async () => {
|
promise_test(async () => {
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
await runTestInPortal(portalSrc, 'testCrossSiteIFrameNavInPortal');
|
await runTestInPortal(portalSrc, 'testCrossSiteIFrameNavInPortal');
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
}, 'Cross site iframe navigates itself independently in a portal');
|
}, 'Cross site iframe navigates itself independently with replacement in a portal');
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
await runTestInPortal(portalSrc, 'testHistoryPushStateInPortal');
|
await runTestInPortal(portalSrc, 'testHistoryPushStateInPortal');
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
}, 'history.pushState navigates independently in a portal');
|
}, 'history.pushState navigates independently with replacement in a portal');
|
||||||
|
|
||||||
promise_test(async () => {
|
promise_test(async () => {
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
await runTestInPortal(portalSrc, 'testLocationAssignInPortal');
|
await runTestInPortal(portalSrc, 'testLocationAssignInPortal');
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
}, 'location.assign navigates independently in a portal');
|
}, 'location.assign navigates independently with replacement in a portal');
|
||||||
|
|
||||||
promise_test(async () => {
|
promise_test(async () => {
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
|
@ -43,12 +43,12 @@
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
await runTestInPortal(portalSrc, 'testSetLocationHrefInPortal');
|
await runTestInPortal(portalSrc, 'testSetLocationHrefInPortal');
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
}, 'Setting location.href navigates independently in a portal');
|
}, 'Setting location.href navigates independently with replacement in a portal');
|
||||||
|
|
||||||
promise_test(async () => {
|
promise_test(async () => {
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
await runTestInPortal(portalSrc, 'testSyntheticAnchorClickInPortal');
|
await runTestInPortal(portalSrc, 'testSyntheticAnchorClickInPortal');
|
||||||
assertInitialHistoryState();
|
assertInitialHistoryState();
|
||||||
}, 'Synthetic anchor click navigates independently in a portal');
|
}, 'Synthetic anchor click navigates independently with replacement in a portal');
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -37,10 +37,10 @@
|
||||||
frameHistoryLength =
|
frameHistoryLength =
|
||||||
await messageFrameAndAwaitResponse(iframe, 'reportHistoryLength');
|
await messageFrameAndAwaitResponse(iframe, 'reportHistoryLength');
|
||||||
assert(
|
assert(
|
||||||
history.length == 2, 'History length changed when iframe src set');
|
history.length == 1, 'History length unchanged when iframe src set');
|
||||||
assert(
|
assert(
|
||||||
frameHistoryLength == 2,
|
frameHistoryLength == 1,
|
||||||
'History length in iframe changed when iframe src set');
|
'History length in iframe unchanged when iframe src set');
|
||||||
}
|
}
|
||||||
|
|
||||||
function testIFrameSrcInPortal() {
|
function testIFrameSrcInPortal() {
|
||||||
|
@ -66,10 +66,10 @@
|
||||||
let frameHistoryLength =
|
let frameHistoryLength =
|
||||||
await messageFrameAndAwaitResponse(iframe, 'reportHistoryLength');
|
await messageFrameAndAwaitResponse(iframe, 'reportHistoryLength');
|
||||||
assert(
|
assert(
|
||||||
history.length == 2, 'History length changed when iframe navigates');
|
history.length == 1, 'History length unchanged when iframe navigates');
|
||||||
assert(
|
assert(
|
||||||
frameHistoryLength == 2,
|
frameHistoryLength == 1,
|
||||||
'History length in iframe changed when iframe navigates');
|
'History length in iframe unchanged when iframe navigates');
|
||||||
}
|
}
|
||||||
|
|
||||||
function testIFrameNavInPortal() {
|
function testIFrameNavInPortal() {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
history.pushState('teststate', null, null);
|
history.pushState('teststate', null, null);
|
||||||
|
|
||||||
assert(history.length == 2, 'History length changed');
|
assert(history.length == 1, 'History length unchanged');
|
||||||
assert(history.state == 'teststate', 'Update state');
|
assert(history.state == 'teststate', 'Update state');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
let initialLocation = location.href;
|
let initialLocation = location.href;
|
||||||
location.assign('#test');
|
location.assign('#test');
|
||||||
|
|
||||||
assert(history.length == 2, 'History length changed');
|
assert(history.length == 1, 'History length unchanged');
|
||||||
assert(location.href != initialLocation, 'Update location');
|
assert(location.href != initialLocation, 'Update location');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
let initialLocation = location.href;
|
let initialLocation = location.href;
|
||||||
location.href = '#test';
|
location.href = '#test';
|
||||||
|
|
||||||
assert(history.length == 2, 'History length changed');
|
assert(history.length == 1, 'History length unchanged');
|
||||||
assert(location.href != initialLocation, 'Update location');
|
assert(location.href != initialLocation, 'Update location');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
|
|
||||||
anchor.click();
|
anchor.click();
|
||||||
|
|
||||||
assert(history.length == 2, 'History length changed');
|
assert(history.length == 1, 'History length unchanged');
|
||||||
assert(location.href != initialLocation, 'Update location');
|
assert(location.href != initialLocation, 'Update location');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
Content-Type: text/css;charset=utf-8
|
|
||||||
Cache-Control: max-age=3600
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
spec: https://wicg.github.io/ScrollToTextFragment/
|
||||||
|
suggested_reviewers:
|
||||||
|
- nburris
|
||||||
|
- bokan
|
|
@ -0,0 +1,78 @@
|
||||||
|
<!doctype html>
|
||||||
|
<title>Navigating to a text fragment directive</title>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<link rel="help" href="https://wicg.github.io/ScrollToTextFragment/">
|
||||||
|
<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="/common/utils.js"></script>
|
||||||
|
<script src="stash.js"></script>
|
||||||
|
<script>
|
||||||
|
// Test security restriction for user activation
|
||||||
|
for (let user_activation of [true, false]) {
|
||||||
|
promise_test(t => new Promise((resolve, reject) => {
|
||||||
|
let key = token();
|
||||||
|
|
||||||
|
if (user_activation) {
|
||||||
|
test_driver.bless('Open a URL with a text fragment directive', () => {
|
||||||
|
window.open(`scroll-to-text-fragment-target.html?key=${key}#:~:text=test`, '_blank', 'noopener');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.open(`scroll-to-text-fragment-target.html?key=${key}#:~:text=test`, '_blank', 'noopener');
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchResults(key, resolve, reject);
|
||||||
|
}).then(data => {
|
||||||
|
assert_equals(data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.');
|
||||||
|
|
||||||
|
if (user_activation) {
|
||||||
|
assert_equals(data.scrollPosition, 'text', 'Expected window.open() with a user activation to scroll to text.');
|
||||||
|
} else {
|
||||||
|
assert_equals(data.scrollPosition, 'top', 'Expected window.open() with no user activation to not activate text fragment directive.');
|
||||||
|
}
|
||||||
|
}), `Test that a text fragment directive requires a user activation (user_activation=${user_activation}).`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test security restriction for no window opener
|
||||||
|
for (let noopener of [true, false]) {
|
||||||
|
promise_test(t => new Promise((resolve, reject) => {
|
||||||
|
let key = token();
|
||||||
|
|
||||||
|
test_driver.bless('Open a URL with a text fragment directive', () => {
|
||||||
|
if (noopener) {
|
||||||
|
window.open(`scroll-to-text-fragment-target.html?key=${key}#:~:text=test`, '_blank', 'noopener');
|
||||||
|
} else {
|
||||||
|
window.open(`scroll-to-text-fragment-target.html?key=${key}#:~:text=test`, '_blank');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchResults(key, resolve, reject);
|
||||||
|
}).then(data => {
|
||||||
|
assert_equals(data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.');
|
||||||
|
|
||||||
|
if (noopener) {
|
||||||
|
assert_equals(data.scrollPosition, 'text', 'Expected window.open() with noopener to scroll to text.');
|
||||||
|
} else {
|
||||||
|
assert_equals(data.scrollPosition, 'top', 'Expected window.open() with opener to not activate text fragment directive.');
|
||||||
|
}
|
||||||
|
}), `Test that a text fragment directive is not activated when there is a window opener (noopener=${noopener}).`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test security restriction for no activation in an iframe
|
||||||
|
promise_test(t => new Promise((resolve, reject) => {
|
||||||
|
let key = token();
|
||||||
|
|
||||||
|
let frame = document.createElement('iframe');
|
||||||
|
document.body.appendChild(frame);
|
||||||
|
|
||||||
|
test_driver.bless('Navigate the iframe with a text fragment directive', () => {
|
||||||
|
frame.src = `scroll-to-text-fragment-target.html?key=${key}#:~:text=test`;
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchResults(key, resolve, reject);
|
||||||
|
}).then(data => {
|
||||||
|
assert_equals(data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.');
|
||||||
|
assert_equals(data.scrollPosition, 'top', 'Expected iframe navigation to not activate text fragment directive.');
|
||||||
|
}), 'Test that a text fragment directive is not activated within an iframe.');
|
||||||
|
</script>
|
|
@ -1,5 +1,6 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<title>Navigating to a text fragment anchor</title>
|
<title>Navigating to a text fragment anchor</title>
|
||||||
|
<script src="stash.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function isInView(element) {
|
function isInView(element) {
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
|
@ -8,8 +9,6 @@ function isInView(element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkScroll() {
|
function checkScroll() {
|
||||||
let bc = new BroadcastChannel('scroll-to-text-fragment');
|
|
||||||
|
|
||||||
let position = 'unknown';
|
let position = 'unknown';
|
||||||
if (window.scrollY == 0)
|
if (window.scrollY == 0)
|
||||||
position = 'top';
|
position = 'top';
|
||||||
|
@ -30,9 +29,10 @@ function checkScroll() {
|
||||||
else if (isInView(document.getElementById('horizontal-scroll')) && window.scrollX > 0)
|
else if (isInView(document.getElementById('horizontal-scroll')) && window.scrollX > 0)
|
||||||
position = 'horizontal-scroll';
|
position = 'horizontal-scroll';
|
||||||
|
|
||||||
bc.postMessage({ scrollPosition: position, href: window.location.href });
|
let results = { scrollPosition: position, href: window.location.href };
|
||||||
bc.close();
|
|
||||||
window.close();
|
let key = (new URL(document.location)).searchParams.get("key");
|
||||||
|
stashResults(key, results);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -7,6 +7,16 @@
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="/resources/testdriver.js"></script>
|
<script src="/resources/testdriver.js"></script>
|
||||||
<script src="/resources/testdriver-vendor.js"></script>
|
<script src="/resources/testdriver-vendor.js"></script>
|
||||||
|
<script src="/common/utils.js"></script>
|
||||||
|
<script src="stash.js"></script>
|
||||||
|
<!--
|
||||||
|
This test suite performs scroll to text navigations to
|
||||||
|
scroll-to-text-fragment-target.html and then checks the results, which are
|
||||||
|
communicated back from the target page via the WPT Stash server (see stash.py).
|
||||||
|
This structure is necessary because scroll to text security restrictions
|
||||||
|
specifically restrict the navigator from being able to observe the result of
|
||||||
|
the navigation, e.g. the target page cannot have a window opener.
|
||||||
|
-->
|
||||||
<script>
|
<script>
|
||||||
let test_cases = [
|
let test_cases = [
|
||||||
// Test non-text fragment directives
|
// Test non-text fragment directives
|
||||||
|
@ -217,82 +227,18 @@ let test_cases = [
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const test_case of test_cases) {
|
for (const test_case of test_cases) {
|
||||||
promise_test(t => new Promise(resolve => {
|
promise_test(t => new Promise((resolve, reject) => {
|
||||||
let channel = new BroadcastChannel('scroll-to-text-fragment');
|
let key = token();
|
||||||
channel.addEventListener("message", e => {
|
|
||||||
resolve(e.data);
|
|
||||||
}, {once: true});
|
|
||||||
|
|
||||||
test_driver.bless('Open a URL with a text fragment directive', () => {
|
test_driver.bless('Open a URL with a text fragment directive', () => {
|
||||||
window.open('scroll-to-text-fragment-target.html' + test_case.fragment, '_blank', 'noopener');
|
window.open(`scroll-to-text-fragment-target.html?key=${key}${test_case.fragment}`, '_blank', 'noopener');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fetchResults(key, resolve, reject);
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
assert_equals(data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.');
|
assert_equals(data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.');
|
||||||
assert_equals(data.scrollPosition, test_case.expect_position,
|
assert_equals(data.scrollPosition, test_case.expect_position,
|
||||||
`Expected ${test_case.fragment} (${test_case.description}) to scroll to ${test_case.expect_position}.`);
|
`Expected ${test_case.fragment} (${test_case.description}) to scroll to ${test_case.expect_position}.`);
|
||||||
}), `Test navigation with fragment: ${test_case.description}.`);
|
}), `Test navigation with fragment: ${test_case.description}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
promise_test(t => new Promise(resolve => {
|
|
||||||
let channel = new BroadcastChannel('scroll-to-text-fragment');
|
|
||||||
channel.addEventListener("message", e => {
|
|
||||||
assert_equals(e.data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.');
|
|
||||||
|
|
||||||
// The first navigation has no user activation.
|
|
||||||
assert_equals(e.data.scrollPosition, 'top', 'Expected window.open() with no user activation to not activate text fragment directive.');
|
|
||||||
|
|
||||||
// Now ensure that a navigation with a user activation does activate the text fragment directive.
|
|
||||||
test_driver.bless('Open a URL with a text fragment directive', () => {
|
|
||||||
window.open('scroll-to-text-fragment-target.html#:~:text=test', '_blank', 'noopener');
|
|
||||||
});
|
|
||||||
channel.addEventListener("message", e => {
|
|
||||||
resolve(e.data.scrollPosition);
|
|
||||||
}, {once: true});
|
|
||||||
}, {once: true});
|
|
||||||
|
|
||||||
window.open('scroll-to-text-fragment-target.html#:~:text=test', '_blank', 'noopener');
|
|
||||||
}).then(scrollPosition => {
|
|
||||||
assert_equals(scrollPosition, 'text', 'Expected window.open() with a user activation to scroll to text.');
|
|
||||||
}), 'Test that a text fragment directive is not activated without a user activation');
|
|
||||||
|
|
||||||
promise_test(t => new Promise(resolve => {
|
|
||||||
let channel = new BroadcastChannel('scroll-to-text-fragment');
|
|
||||||
channel.addEventListener("message", e => {
|
|
||||||
assert_equals(e.data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.');
|
|
||||||
|
|
||||||
// The first navigation has an opener.
|
|
||||||
assert_equals(e.data.scrollPosition, 'top', 'Expected window.open() with opener to not activate text fragment directive.');
|
|
||||||
|
|
||||||
// Now ensure that a navigation with noopener does activate the text fragment directive.
|
|
||||||
test_driver.bless('Open a URL with a text fragment directive', () => {
|
|
||||||
window.open('scroll-to-text-fragment-target.html#:~:text=test', '_blank', 'noopener');
|
|
||||||
});
|
|
||||||
channel.addEventListener("message", e => {
|
|
||||||
resolve(e.data.scrollPosition);
|
|
||||||
}, {once: true});
|
|
||||||
}, {once: true});
|
|
||||||
|
|
||||||
test_driver.bless('Open a URL with a text fragment directive', () => {
|
|
||||||
window.open('scroll-to-text-fragment-target.html#:~:text=test', '_blank');
|
|
||||||
});
|
|
||||||
}).then(scrollPosition => {
|
|
||||||
assert_equals(scrollPosition, 'text', 'Expected window.open() with noopener to scroll to text.');
|
|
||||||
}), 'Test that a text fragment directive is not activated when there is a window opener.');
|
|
||||||
|
|
||||||
promise_test(t => new Promise(resolve => {
|
|
||||||
let channel = new BroadcastChannel('scroll-to-text-fragment');
|
|
||||||
channel.addEventListener("message", e => {
|
|
||||||
resolve(e.data);
|
|
||||||
}, {once: true});
|
|
||||||
|
|
||||||
let frame = document.createElement('iframe');
|
|
||||||
document.body.appendChild(frame);
|
|
||||||
|
|
||||||
test_driver.bless('Navigate the iframe with a text fragment directive', () => {
|
|
||||||
frame.src = 'scroll-to-text-fragment-target.html#:~:text=test';
|
|
||||||
});
|
|
||||||
}).then(data => {
|
|
||||||
assert_equals(data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.');
|
|
||||||
assert_equals(data.scrollPosition, 'top', 'Expected iframe navigation to not activate text fragment directive.');
|
|
||||||
}), 'Test that a text fragment directive is not activated within an iframe.');
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Put test results into Stash
|
||||||
|
function stashResults(key, results) {
|
||||||
|
fetch(`/scroll-to-text-fragment/stash.py?key=${key}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(results)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch test results from the Stash
|
||||||
|
function fetchResults(key, resolve, reject) {
|
||||||
|
fetch(`/scroll-to-text-fragment/stash.py?key=${key}`).then(response => {
|
||||||
|
return response.text();
|
||||||
|
}).then(text => {
|
||||||
|
if (text) {
|
||||||
|
try {
|
||||||
|
const results = JSON.parse(text);
|
||||||
|
resolve(results);
|
||||||
|
} catch(e) {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
def main(request, response):
|
||||||
|
key = request.GET.first("key")
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
# Received result data from target page
|
||||||
|
request.server.stash.put(key, request.body, '/scroll-to-text-fragment/')
|
||||||
|
return "ok"
|
||||||
|
else:
|
||||||
|
# Request for result data from test page
|
||||||
|
value = request.server.stash.take(key, '/scroll-to-text-fragment/')
|
||||||
|
# Poll until data is stashed
|
||||||
|
while value is None:
|
||||||
|
time.sleep(.1)
|
||||||
|
value = request.server.stash.take(key, '/scroll-to-text-fragment/')
|
||||||
|
return value
|
|
@ -188,3 +188,13 @@ for (const preventCancel of [true, false]) {
|
||||||
|
|
||||||
}, `an undefined rejection from write should cause pipeTo() to reject when preventCancel is ${preventCancel}`);
|
}, `an undefined rejection from write should cause pipeTo() to reject when preventCancel is ${preventCancel}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
promise_test(t => {
|
||||||
|
const rs = new ReadableStream();
|
||||||
|
const ws = new WritableStream();
|
||||||
|
return promise_rejects(t, new TypeError(), rs.pipeTo(ws, {
|
||||||
|
get preventAbort() {
|
||||||
|
ws.getWriter();
|
||||||
|
}
|
||||||
|
}), 'pipeTo should reject');
|
||||||
|
}, 'pipeTo() should reject if an option getter grabs a writer');
|
||||||
|
|
|
@ -253,3 +253,14 @@ promise_test(() => {
|
||||||
assert_array_equals(writable.events, [], 'writable should not be aborted');
|
assert_array_equals(writable.events, [], 'writable should not be aborted');
|
||||||
});
|
});
|
||||||
}, 'preventAbort should work');
|
}, 'preventAbort should work');
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const rs = new ReadableStream();
|
||||||
|
const readable = new ReadableStream();
|
||||||
|
const writable = new WritableStream();
|
||||||
|
assert_throws(new TypeError(), () => rs.pipeThrough({readable, writable}, {
|
||||||
|
get preventAbort() {
|
||||||
|
writable.getWriter();
|
||||||
|
}
|
||||||
|
}), 'pipeThrough should throw');
|
||||||
|
}, 'pipeThrough() should throw if an option getter grabs a writer');
|
||||||
|
|
|
@ -11,7 +11,6 @@ steps:
|
||||||
- template: pip_install.yml
|
- template: pip_install.yml
|
||||||
parameters:
|
parameters:
|
||||||
packages: virtualenv
|
packages: virtualenv
|
||||||
- template: install_fonts.yml
|
|
||||||
- template: install_certs.yml
|
- template: install_certs.yml
|
||||||
- template: install_safari.yml
|
- template: install_safari.yml
|
||||||
- template: update_hosts.yml
|
- template: update_hosts.yml
|
||||||
|
|
|
@ -9,7 +9,8 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
browser_specific_args = {
|
browser_specific_args = {
|
||||||
"firefox": ["--install-browser"]
|
"firefox": ["--install-browser"],
|
||||||
|
"servo": ["--install-browser", "--processes=12"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,6 +68,10 @@ def main(product, commit_range, wpt_args):
|
||||||
]
|
]
|
||||||
wpt_args += browser_specific_args.get(product, [])
|
wpt_args += browser_specific_args.get(product, [])
|
||||||
|
|
||||||
|
# Hack to run servo with one process only for wdspec
|
||||||
|
if product == "servo" and "--test-type=wdspec" in wpt_args:
|
||||||
|
wpt_args = [item for item in wpt_args if not item.startswith("--processes")]
|
||||||
|
|
||||||
command = ["python", "./wpt", "run"] + wpt_args + [product]
|
command = ["python", "./wpt", "run"] + wpt_args + [product]
|
||||||
|
|
||||||
logger.info("Executing command: %s" % " ".join(command))
|
logger.info("Executing command: %s" % " ".join(command))
|
||||||
|
|
|
@ -4,7 +4,7 @@ components:
|
||||||
workerType: ci
|
workerType: ci
|
||||||
schedulerId: taskcluster-github
|
schedulerId: taskcluster-github
|
||||||
deadline: "24 hours"
|
deadline: "24 hours"
|
||||||
image: harjgam/web-platform-tests:0.33
|
image: harjgam/web-platform-tests:0.34
|
||||||
maxRunTime: 7200
|
maxRunTime: 7200
|
||||||
artifacts:
|
artifacts:
|
||||||
public/results:
|
public/results:
|
||||||
|
|
|
@ -15,8 +15,11 @@ RUN apt-get -qqy update \
|
||||||
fluxbox \
|
fluxbox \
|
||||||
gdebi \
|
gdebi \
|
||||||
git \
|
git \
|
||||||
|
gstreamer1.0-plugins-bad \
|
||||||
|
libosmesa6-dev \
|
||||||
libvirt-daemon-system \
|
libvirt-daemon-system \
|
||||||
libvirt-clients \
|
libvirt-clients \
|
||||||
|
libunwind8 \
|
||||||
locales \
|
locales \
|
||||||
openjdk-8-jre-headless \
|
openjdk-8-jre-headless \
|
||||||
pulseaudio \
|
pulseaudio \
|
||||||
|
|
|
@ -484,10 +484,6 @@ def check_parsed(repo_root, path, f):
|
||||||
if len(testharnessreport_nodes) > 1:
|
if len(testharnessreport_nodes) > 1:
|
||||||
errors.append(rules.MultipleTestharnessReport.error(path))
|
errors.append(rules.MultipleTestharnessReport.error(path))
|
||||||
|
|
||||||
testharnesscss_nodes = source_file.root.findall(".//{http://www.w3.org/1999/xhtml}link[@href='/resources/testharness.css']")
|
|
||||||
if testharnesscss_nodes:
|
|
||||||
errors.append(rules.PresentTestharnessCSS.error(path))
|
|
||||||
|
|
||||||
for element in source_file.variant_nodes:
|
for element in source_file.variant_nodes:
|
||||||
if "content" not in element.attrib:
|
if "content" not in element.attrib:
|
||||||
errors.append(rules.VariantMissing.error(path))
|
errors.append(rules.VariantMissing.error(path))
|
||||||
|
|
|
@ -199,11 +199,6 @@ class MultipleTestharnessReport(Rule):
|
||||||
description = "More than one `<script src='/resources/testharnessreport.js'>`"
|
description = "More than one `<script src='/resources/testharnessreport.js'>`"
|
||||||
|
|
||||||
|
|
||||||
class PresentTestharnessCSS(Rule):
|
|
||||||
name = "PRESENT-TESTHARNESSCSS"
|
|
||||||
description = "Explicit link to testharness.css present"
|
|
||||||
|
|
||||||
|
|
||||||
class VariantMissing(Rule):
|
class VariantMissing(Rule):
|
||||||
name = "VARIANT-MISSING"
|
name = "VARIANT-MISSING"
|
||||||
description = collapse("""
|
description = collapse("""
|
||||||
|
|
|
@ -410,29 +410,6 @@ def test_missing_testdriver_vendor():
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_present_testharnesscss():
|
|
||||||
code = b"""
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<link rel="stylesheet" href="/resources/testharness.css"/>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
error_map = check_with_files(code)
|
|
||||||
|
|
||||||
for (filename, (errors, kind)) in error_map.items():
|
|
||||||
check_errors(errors)
|
|
||||||
|
|
||||||
if kind in ["web-lax", "web-strict"]:
|
|
||||||
assert errors == [
|
|
||||||
("PRESENT-TESTHARNESSCSS", "Explicit link to testharness.css present", filename, None),
|
|
||||||
]
|
|
||||||
elif kind == "python":
|
|
||||||
assert errors == [
|
|
||||||
("PARSE-FAILED", "Unable to parse file", filename, 2),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_testharness_path():
|
def test_testharness_path():
|
||||||
code = b"""\
|
code = b"""\
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
|
@ -46,6 +46,7 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
|
||||||
rv["pause_after_test"] = kwargs["pause_after_test"]
|
rv["pause_after_test"] = kwargs["pause_after_test"]
|
||||||
if test_type == "wdspec":
|
if test_type == "wdspec":
|
||||||
rv["capabilities"] = {}
|
rv["capabilities"] = {}
|
||||||
|
rv["webdriver_binary"] = kwargs["binary"]
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ class TimedRunner(object):
|
||||||
executor = threading.Thread(target=self.run_func)
|
executor = threading.Thread(target=self.run_func)
|
||||||
executor.start()
|
executor.start()
|
||||||
|
|
||||||
# Add twice the timeout multiplier since the called function is expected to
|
# Add twice the extra timeout since the called function is expected to
|
||||||
# wait at least self.timeout + self.extra_timeout and this gives some leeway
|
# wait at least self.timeout + self.extra_timeout and this gives some leeway
|
||||||
timeout = self.timeout + 2 * self.extra_timeout if self.timeout else None
|
timeout = self.timeout + 2 * self.extra_timeout if self.timeout else None
|
||||||
finished = self.result_flag.wait(timeout)
|
finished = self.result_flag.wait(timeout)
|
||||||
|
@ -654,6 +654,8 @@ class CallbackHandler(object):
|
||||||
WebDriver. Things that are more different to WebDriver may need to create a
|
WebDriver. Things that are more different to WebDriver may need to create a
|
||||||
fully custom implementation."""
|
fully custom implementation."""
|
||||||
|
|
||||||
|
unimplemented_exc = (NotImplementedError,)
|
||||||
|
|
||||||
def __init__(self, logger, protocol, test_window):
|
def __init__(self, logger, protocol, test_window):
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
self.test_window = test_window
|
self.test_window = test_window
|
||||||
|
@ -700,6 +702,9 @@ class CallbackHandler(object):
|
||||||
raise ValueError("Unknown action %s" % action)
|
raise ValueError("Unknown action %s" % action)
|
||||||
try:
|
try:
|
||||||
result = action_handler(payload)
|
result = action_handler(payload)
|
||||||
|
except self.unimplemented_exc:
|
||||||
|
self.logger.warning("Action %s not implemented" % action)
|
||||||
|
self._send_message("complete", "error", "Action %s not implemented" % action)
|
||||||
except Exception:
|
except Exception:
|
||||||
self.logger.warning("Action %s failed" % action)
|
self.logger.warning("Action %s failed" % action)
|
||||||
self.logger.warning(traceback.format_exc())
|
self.logger.warning(traceback.format_exc())
|
||||||
|
|
|
@ -31,7 +31,10 @@ from .protocol import (ActionSequenceProtocolPart,
|
||||||
ClickProtocolPart,
|
ClickProtocolPart,
|
||||||
SendKeysProtocolPart,
|
SendKeysProtocolPart,
|
||||||
TestDriverProtocolPart,
|
TestDriverProtocolPart,
|
||||||
CoverageProtocolPart)
|
CoverageProtocolPart,
|
||||||
|
GenerateTestReportProtocolPart,
|
||||||
|
VirtualAuthenticatorProtocolPart,
|
||||||
|
SetPermissionProtocolPart)
|
||||||
from ..testrunner import Stop
|
from ..testrunner import Stop
|
||||||
from ..webdriver_server import GeckoDriverServer
|
from ..webdriver_server import GeckoDriverServer
|
||||||
|
|
||||||
|
@ -481,6 +484,44 @@ class MarionetteCoverageProtocolPart(CoverageProtocolPart):
|
||||||
# This usually happens if the process crashed
|
# This usually happens if the process crashed
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class MarionetteGenerateTestReportProtocolPart(GenerateTestReportProtocolPart):
|
||||||
|
def setup(self):
|
||||||
|
self.marionette = self.parent.marionette
|
||||||
|
|
||||||
|
def generate_test_report(self, config):
|
||||||
|
raise NotImplementedError("generate_test_report not yet implemented")
|
||||||
|
|
||||||
|
class MarionetteVirtualAuthenticatorProtocolPart(VirtualAuthenticatorProtocolPart):
|
||||||
|
def setup(self):
|
||||||
|
self.marionette = self.parent.marionette
|
||||||
|
|
||||||
|
def add_virtual_authenticator(self, config):
|
||||||
|
raise NotImplementedError("add_virtual_authenticator not yet implemented")
|
||||||
|
|
||||||
|
def remove_virtual_authenticator(self, authenticator_id):
|
||||||
|
raise NotImplementedError("remove_virtual_authenticator not yet implemented")
|
||||||
|
|
||||||
|
def add_credential(self, authenticator_id, credential):
|
||||||
|
raise NotImplementedError("add_credential not yet implemented")
|
||||||
|
|
||||||
|
def get_credentials(self, authenticator_id):
|
||||||
|
raise NotImplementedError("get_credentials not yet implemented")
|
||||||
|
|
||||||
|
def remove_credential(self, authenticator_id, credential_id):
|
||||||
|
raise NotImplementedError("remove_credential not yet implemented")
|
||||||
|
|
||||||
|
def remove_all_credentials(self, authenticator_id):
|
||||||
|
raise NotImplementedError("remove_all_credentials not yet implemented")
|
||||||
|
|
||||||
|
def set_user_verified(self, authenticator_id, uv):
|
||||||
|
raise NotImplementedError("set_user_verified not yet implemented")
|
||||||
|
|
||||||
|
class MarionetteSetPermissionProtocolPart(SetPermissionProtocolPart):
|
||||||
|
def setup(self):
|
||||||
|
self.marionette = self.parent.marionette
|
||||||
|
|
||||||
|
def set_permission(self, name, state, one_realm):
|
||||||
|
raise NotImplementedError("set_permission not yet implemented")
|
||||||
|
|
||||||
class MarionetteProtocol(Protocol):
|
class MarionetteProtocol(Protocol):
|
||||||
implements = [MarionetteBaseProtocolPart,
|
implements = [MarionetteBaseProtocolPart,
|
||||||
|
@ -493,7 +534,10 @@ class MarionetteProtocol(Protocol):
|
||||||
MarionetteActionSequenceProtocolPart,
|
MarionetteActionSequenceProtocolPart,
|
||||||
MarionetteTestDriverProtocolPart,
|
MarionetteTestDriverProtocolPart,
|
||||||
MarionetteAssertsProtocolPart,
|
MarionetteAssertsProtocolPart,
|
||||||
MarionetteCoverageProtocolPart]
|
MarionetteCoverageProtocolPart,
|
||||||
|
MarionetteGenerateTestReportProtocolPart,
|
||||||
|
MarionetteVirtualAuthenticatorProtocolPart,
|
||||||
|
MarionetteSetPermissionProtocolPart]
|
||||||
|
|
||||||
def __init__(self, executor, browser, capabilities=None, timeout_multiplier=1, e10s=True, ccov=False):
|
def __init__(self, executor, browser, capabilities=None, timeout_multiplier=1, e10s=True, ccov=False):
|
||||||
do_delayed_imports()
|
do_delayed_imports()
|
||||||
|
|
|
@ -31,6 +31,10 @@ import webdriver as client
|
||||||
here = os.path.join(os.path.split(__file__)[0])
|
here = os.path.join(os.path.split(__file__)[0])
|
||||||
|
|
||||||
|
|
||||||
|
class WebDriverCallbackHandler(CallbackHandler):
|
||||||
|
unimplemented_exc = (NotImplementedError, client.UnknownCommandException)
|
||||||
|
|
||||||
|
|
||||||
class WebDriverBaseProtocolPart(BaseProtocolPart):
|
class WebDriverBaseProtocolPart(BaseProtocolPart):
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.webdriver = self.parent.webdriver
|
self.webdriver = self.parent.webdriver
|
||||||
|
@ -376,7 +380,7 @@ class WebDriverTestharnessExecutor(TestharnessExecutor):
|
||||||
parent_window,
|
parent_window,
|
||||||
timeout=5*self.timeout_multiplier)
|
timeout=5*self.timeout_multiplier)
|
||||||
self.protocol.base.set_window(test_window)
|
self.protocol.base.set_window(test_window)
|
||||||
handler = CallbackHandler(self.logger, protocol, test_window)
|
handler = WebDriverCallbackHandler(self.logger, protocol, test_window)
|
||||||
protocol.webdriver.url = url
|
protocol.webdriver.url = url
|
||||||
|
|
||||||
if not self.supports_eager_pageload:
|
if not self.supports_eager_pageload:
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
result = JSON.parse(data.message).result
|
result = JSON.parse(data.message).result
|
||||||
pending_resolve(result);
|
pending_resolve(result);
|
||||||
} else {
|
} else {
|
||||||
pending_reject();
|
pending_reject(`${data.status}: ${data.message}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue