зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1367340 - Update web-platform-tests to revision a2d29f3497c889546662566721bbd4f86efdbedd, a=testonly
MozReview-Commit-ID: G7hh5RgrlOv --HG-- rename : testing/web-platform/tests/content-security-policy/navigation/to-javascript-url.html => testing/web-platform/tests/content-security-policy/navigation/to-javascript-url-script-src.html rename : testing/web-platform/tests/webusb/idlharness.html => testing/web-platform/tests/webusb/idlharness.https.html
This commit is contained in:
Родитель
4d67546b87
Коммит
3f997c7d6e
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,2 +1,2 @@
|
|||
local: 0b255199db9d6a6f189b89b7906f99155bde3726
|
||||
upstream: 72d174747fe176cbefcba315b445fac99d3dbfb2
|
||||
local: baf05f61bc14fdf45511bc1165ce76daa08c5c0f
|
||||
upstream: bd9c09a11fe2ef9e4718c820bec5599666d3f7ac
|
||||
|
|
|
@ -14,3 +14,4 @@ webdriver/.idea
|
|||
.vscode/
|
||||
.DS_Store
|
||||
*.rej
|
||||
_venv
|
||||
|
|
|
@ -12,6 +12,8 @@ addons:
|
|||
- www2.web-platform.test
|
||||
- xn--n8j6ds53lwwkrqhv28a.web-platform.test
|
||||
- xn--lve-6lad.web-platform.test
|
||||
jwt:
|
||||
secure: N9lvgkqUPtFlz6Vpa6qTPFhymEsDCsbaCsT64/hj3vlHRxK94r5+ugVJ3zm99zC0q2j1ish8yJC7mN/W4wRfBE4sAwmdxrlowxF1DDGCkaLE9i/GWW92s0fBVGJmXLh8kwNkQ31hMOsaGfHIMpeLFS7Se741te7YqsHIzmBCdQs=
|
||||
before_install:
|
||||
- git submodule update --init --recursive
|
||||
- export DISPLAY=:99.0
|
||||
|
@ -20,6 +22,8 @@ install:
|
|||
- pip install -U setuptools
|
||||
- pip install -U requests
|
||||
env: # required at the top-level for allow_failures to work below
|
||||
global:
|
||||
- SAUCE_USERNAME=w3c-ttwf
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
|
@ -52,6 +56,16 @@ matrix:
|
|||
env:
|
||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||
- SCRIPT=ci_stability.sh PRODUCT=chrome:unstable
|
||||
- os: linux
|
||||
python: "2.7"
|
||||
env:
|
||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||
- SCRIPT=ci_stability.sh PRODUCT=sauce:safari:10.0 PLATFORM='macOS 10.12'
|
||||
- os: linux
|
||||
python: "2.7"
|
||||
env:
|
||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||
- SCRIPT=ci_stability.sh PRODUCT=sauce:MicrosoftEdge:14.14393 PLATFORM='Windows 10'
|
||||
- python: 2.7
|
||||
env: TOXENV=py27 HYPOTHESIS_PROFILE=ci SCRIPT=ci_unittest.sh
|
||||
- python: 3.5
|
||||
|
@ -59,7 +73,7 @@ matrix:
|
|||
- python: 3.6
|
||||
env: TOXENV=py36 HYPOTHESIS_PROFILE=ci SCRIPT=ci_unittest.sh
|
||||
- python: pypy
|
||||
env: TOXENV=pypy HYPOTHESIS_PROFILE=ci_pypy SCRIPT=ci_unittest.sh
|
||||
env: TOXENV=pypy HYPOTHESIS_PROFILE=ci SCRIPT=ci_unittest.sh
|
||||
exclude:
|
||||
- env: # exclude empty env from the top-level above
|
||||
allow_failures:
|
||||
|
@ -67,6 +81,9 @@ matrix:
|
|||
- env:
|
||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||
- SCRIPT=ci_stability.sh PRODUCT=chrome:unstable
|
||||
- env:
|
||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||
- SCRIPT=ci_stability.sh PRODUCT=sauce:MicrosoftEdge:14.14393 PLATFORM='Windows 10'
|
||||
script:
|
||||
- bash $SCRIPT
|
||||
cache:
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
...
|
||||
<script>
|
||||
var p = new DOMParser(), s = new XMLSerializer();
|
||||
var doc = p.parseFromString("<!DOCTYPE foo [ <!ELEMENT foo (#PCDATA)> ]><foo/>", "text/xml")
|
||||
w(s.serializeToString(doc))
|
||||
</script>
|
||||
<table>
|
||||
<caption>Results</caption>
|
||||
<thead>
|
||||
<tr><th>UA<th>Result
|
||||
<tbody>
|
||||
<tr><th>Gecko<td><code><!DOCTYPE foo [ <!ELEMENT foo (#PCDATA)> ]>\n<foo/></code>
|
||||
<tr><th>WebKit<td><code><!DOCTYPE foo><foo/></code>
|
||||
<tr><th>Presto<td><code><?xml version="1.0"?><!DOCTYPE foo><foo/></code>
|
||||
</table>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>IDBFactory deleteDatabase(): request properties on success</title>
|
||||
<link rel="help" href="https://w3c.github.io/IndexedDB/#dom-idbfactory-deleteDatabase">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=support.js></script>
|
||||
<script>
|
||||
|
||||
async_test(t => {
|
||||
const dbname = document.location + '-' + t.name;
|
||||
const rq = indexedDB.deleteDatabase(dbname);
|
||||
rq.onerror = t.unreached_func('deleteDatabase should succeed');
|
||||
rq.onsuccess = t.step_func(() => {
|
||||
assert_equals(
|
||||
rq.readyState, 'done',
|
||||
'request done flag should be set on success');
|
||||
assert_equals(
|
||||
rq.result, undefined,
|
||||
'request result should still be set to undefined on success');
|
||||
assert_equals(
|
||||
rq.error, null,
|
||||
'request error should be null on success');
|
||||
t.done();
|
||||
});
|
||||
}, 'Properties of IDBOpenDBRequest during IDBFactory deleteDatabase()');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,66 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>IDBFactory open(): request properties on error</title>
|
||||
<link rel="help" href="https://w3c.github.io/IndexedDB/#dom-idbfactory-open">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=support.js></script>
|
||||
<script>
|
||||
|
||||
let saw_abort = false;
|
||||
|
||||
indexeddb_test(
|
||||
(t, db, tx, rq) => {
|
||||
const store = db.createObjectStore('store');
|
||||
store.put({name: 'a'}, 1);
|
||||
store.put({name: 'a'}, 2);
|
||||
store.createIndex('index', 'name', {unique: true});
|
||||
|
||||
assert_equals(
|
||||
rq.readyState, 'done',
|
||||
'request done flag should be set during upgradeneeded');
|
||||
assert_equals(
|
||||
rq.result, db,
|
||||
'request result should be set (to connection) during upgradeneeded');
|
||||
assert_equals(
|
||||
rq.error, null,
|
||||
'request result should be null during upgradeneeded');
|
||||
|
||||
tx.oncomplete = t.unreached_func('transaction should abort');
|
||||
tx.onabort = t.step_func(() => {
|
||||
saw_abort = true;
|
||||
|
||||
assert_equals(
|
||||
rq.readyState, 'done',
|
||||
'request done flag should still be set during abort');
|
||||
|
||||
// Chrome is flaky here. See: https://crbug.com/723846
|
||||
/*
|
||||
assert_equals(
|
||||
rq.result, db,
|
||||
'request result should still be set (to connection) during abort');
|
||||
assert_equals(
|
||||
rq.error, null,
|
||||
'request result should still be null during abort');
|
||||
*/
|
||||
});
|
||||
|
||||
rq.onerror = t.step_func(() => {
|
||||
assert_true(saw_abort, 'abort event should fire before error');
|
||||
assert_equals(
|
||||
rq.readyState, 'done',
|
||||
'request done flag should be set on error');
|
||||
assert_equals(
|
||||
rq.result, undefined,
|
||||
'request result should be undefined on error');
|
||||
assert_equals(
|
||||
rq.error.name, 'AbortError',
|
||||
'request error should be AbortError on error');
|
||||
t.done();
|
||||
});
|
||||
},
|
||||
(t, db) => {},
|
||||
'Properties of IDBOpenDBRequest during failed IDBFactory open()',
|
||||
{upgrade_will_abort: true});
|
||||
|
||||
</script>
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>IDBFactory open(): request properties on success</title>
|
||||
<link rel="help" href="https://w3c.github.io/IndexedDB/#dom-idbfactory-open">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=support.js></script>
|
||||
<script>
|
||||
|
||||
let saw_complete = false;
|
||||
|
||||
indexeddb_test(
|
||||
(t, db, tx, rq) => {
|
||||
assert_equals(
|
||||
rq.readyState, 'done',
|
||||
'request done flag should be set during upgradeneeded');
|
||||
assert_equals(
|
||||
rq.result, db,
|
||||
'request result should be set (to connection) during upgradeneeded');
|
||||
assert_equals(
|
||||
rq.error, null,
|
||||
'request result should be null during upgradeneeded');
|
||||
|
||||
tx.onabort = t.unreached_func('transaction should complete');
|
||||
tx.oncomplete = t.step_func(() => {
|
||||
saw_complete = true;
|
||||
|
||||
assert_equals(
|
||||
rq.readyState, 'done',
|
||||
'request done flag should still be set during complete');
|
||||
assert_equals(
|
||||
rq.result, db,
|
||||
'request result should still be set (to connection) during complete');
|
||||
assert_equals(
|
||||
rq.error, null,
|
||||
'request result should still be null during complete');
|
||||
});
|
||||
},
|
||||
(t, db, rq) => {
|
||||
assert_true(saw_complete, 'complete event should fire before success');
|
||||
assert_equals(
|
||||
rq.readyState, 'done',
|
||||
'request done flag should be set on success');
|
||||
assert_equals(
|
||||
rq.result, db,
|
||||
'request result should still be set (to connection) on success');
|
||||
assert_equals(
|
||||
rq.error, null,
|
||||
'request error should be null on success');
|
||||
t.done();
|
||||
},
|
||||
'Properties of IDBOpenDBRequest during successful IDBFactory open()');
|
||||
|
||||
</script>
|
|
@ -122,7 +122,7 @@ function indexeddb_test(upgrade_func, open_func, description, options) {
|
|||
indexedDB.deleteDatabase(db.name);
|
||||
});
|
||||
var tx = open.transaction;
|
||||
upgrade_func(t, db, tx);
|
||||
upgrade_func(t, db, tx, open);
|
||||
});
|
||||
if (options.upgrade_will_abort) {
|
||||
open.onsuccess = t.unreached_func('open should not succeed');
|
||||
|
@ -131,7 +131,7 @@ function indexeddb_test(upgrade_func, open_func, description, options) {
|
|||
open.onsuccess = t.step_func(function() {
|
||||
var db = open.result;
|
||||
if (open_func)
|
||||
open_func(t, db);
|
||||
open_func(t, db, open);
|
||||
});
|
||||
}
|
||||
}, description);
|
||||
|
|
|
@ -70,6 +70,42 @@ like:
|
|||
"ssl": {"openssl": {"binary": "/path/to/openssl"}}
|
||||
```
|
||||
|
||||
Running Tests Automatically
|
||||
---------------------------
|
||||
|
||||
Tests can be run automatically in a browser using the `wptrun` script
|
||||
in the root of the checkout. This requires the hosts file and OpenSSL
|
||||
setup documented above, but you must *not* have the test server
|
||||
already running when calling `wptrun`. The basic command line syntax
|
||||
is:
|
||||
|
||||
```
|
||||
./wptrun product [tests]
|
||||
```
|
||||
|
||||
where `product` is currently `firefox` or `chrome` and `[tests]` is a
|
||||
list of paths to tests. This will attempt to automatically locate a
|
||||
browser instance and install required dependencies. The command is
|
||||
very configurable; for examaple to specify a particular binary use
|
||||
`wptrun --binary=path product`. The full range of options can be see
|
||||
with `wptrun --help` and `wptrun --wptrunner-help`.
|
||||
|
||||
Not all dependencies can be automatically installed; in particular the
|
||||
`certutil` tool required to run https tests with Firefox must be
|
||||
installed using a system package manager or similar.
|
||||
|
||||
On Debian/Ubuntu certutil may be installed using:
|
||||
|
||||
```
|
||||
sudo apt install libnss3-tools
|
||||
```
|
||||
|
||||
And on macOS with homebrew using:
|
||||
|
||||
```
|
||||
brew install nss
|
||||
```
|
||||
|
||||
<span id="submodules">Submodules</span>
|
||||
=======================================
|
||||
|
||||
|
@ -228,16 +264,16 @@ your local web-platform-tests working directory like this:
|
|||
|
||||
The lint tool is also run automatically for every submitted pull
|
||||
request, and reviewers will not merge branches with tests that have
|
||||
lint errors, so you must fix any errors the lint tool reports. For
|
||||
details on doing that, see the [lint-tool documentation][lint-tool].
|
||||
lint errors, so you must fix any errors the lint tool reports.
|
||||
|
||||
But in the unusual case of error reports for things essential to a
|
||||
In the unusual case of error reports for things essential to a
|
||||
certain test or that for other exceptional reasons shouldn't prevent
|
||||
a merge of a test, update and commit the `lint.whitelist` file in the
|
||||
web-platform-tests root directory to suppress the error reports. For
|
||||
details on doing that, see the [lint-tool documentation][lint-tool].
|
||||
web-platform-tests root directory to suppress the error reports.
|
||||
|
||||
[lint-tool]: https://github.com/w3c/web-platform-tests/blob/master/docs/lint-tool.md
|
||||
For more details, see the [lint-tool documentation][lint-tool].
|
||||
|
||||
[lint-tool]: http://web-platform-tests.org/writing-tests/lint-tool.html
|
||||
|
||||
Adding command-line scripts ("tools" subdirs)
|
||||
---------------------------------------------
|
||||
|
@ -305,5 +341,5 @@ is [archived][ircarchive].
|
|||
Documentation
|
||||
=============
|
||||
|
||||
* [How to write and review tests](http://testthewebforward.org/docs/)
|
||||
* [How to write and review tests](http://web-platform-tests.org/)
|
||||
* [Documentation for the wptserve server](http://wptserve.readthedocs.org/en/latest/)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
@domenic
|
||||
@jensl
|
||||
@tobie
|
||||
@yuki3
|
|
@ -0,0 +1,117 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>[PutForwards] behavior</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="author" title="Jens Widell" href="mailto:jl@opera.com">
|
||||
<link rel="help" href="https://heycam.github.io/webidl/#PutForwards">
|
||||
|
||||
<script>
|
||||
test(() => {
|
||||
var getter_called = false;
|
||||
var element = document.createElement("div");
|
||||
var element_style = element.style;
|
||||
var descriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "style");
|
||||
|
||||
Object.defineProperty(element, "style", {
|
||||
get: function () {
|
||||
getter_called = true;
|
||||
return element_style;
|
||||
},
|
||||
set: descriptor.set
|
||||
});
|
||||
|
||||
element.style = "color: green";
|
||||
|
||||
assert_true(getter_called, "Overridden getter should be called");
|
||||
assert_equals(element_style.color, "green", "Put forwarding still works");
|
||||
}, "Overriding getter of [PutForwards] attribute");
|
||||
|
||||
test(() => {
|
||||
var setter_called = false;
|
||||
var element = document.createElement("div");
|
||||
var element_style = element.style;
|
||||
var descriptor = Object.getOwnPropertyDescriptor(CSSStyleDeclaration.prototype, "cssText");
|
||||
|
||||
Object.defineProperty(element_style, "cssText", {
|
||||
get: descriptor.get,
|
||||
set: function (v) {
|
||||
setter_called = true;
|
||||
descriptor.set.call(this, v);
|
||||
}
|
||||
});
|
||||
|
||||
element.style = "color: green";
|
||||
|
||||
assert_true(setter_called, "Overridden setter should be called");
|
||||
assert_equals(element_style.color, "green", "Put forwarding still works");
|
||||
}, "Overriding setter of [PutForwards] target attribute");
|
||||
|
||||
test(() => {
|
||||
var element = document.createElement("div");
|
||||
var element_style = element.style;
|
||||
var fake_style = { cssText: "original" };
|
||||
var descriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "style");
|
||||
|
||||
Object.defineProperty(element, "style", {
|
||||
get: function () {
|
||||
return fake_style;
|
||||
},
|
||||
set: descriptor.set
|
||||
});
|
||||
|
||||
element.style = "color: green";
|
||||
|
||||
assert_equals(element_style.cssText, "", "Original value intact");
|
||||
assert_equals(fake_style.cssText, "color: green", "Fake style object updated");
|
||||
}, "Overriding target of [PutForwards] attribute");
|
||||
|
||||
test(() => {
|
||||
var element = document.createElement("div");
|
||||
var descriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "style");
|
||||
|
||||
Object.defineProperty(element, "style", {
|
||||
get: function () {
|
||||
throw new SyntaxError();
|
||||
},
|
||||
set: descriptor.set
|
||||
});
|
||||
|
||||
assert_throws(new SyntaxError(), () => {
|
||||
element.style = "color: green";
|
||||
});
|
||||
}, "Exception propagation from getter of [PutForwards] attribute");
|
||||
|
||||
test(() => {
|
||||
var element = document.createElement("div");
|
||||
var element_style = element.style;
|
||||
var descriptor = Object.getOwnPropertyDescriptor(CSSStyleDeclaration.prototype, "cssText");
|
||||
|
||||
Object.defineProperty(element_style, "cssText", {
|
||||
get: descriptor.get,
|
||||
set: function (v) {
|
||||
throw new SyntaxError();
|
||||
}
|
||||
});
|
||||
|
||||
assert_throws(new SyntaxError(), () => {
|
||||
element.style = "color: green";
|
||||
});
|
||||
}, "Exception propagation from setter of [PutForwards] target attribute");
|
||||
|
||||
test(() => {
|
||||
var element = document.createElement("div");
|
||||
var descriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "style");
|
||||
|
||||
Object.defineProperty(element, "style", {
|
||||
get: function () {
|
||||
return null;
|
||||
},
|
||||
set: descriptor.set
|
||||
});
|
||||
|
||||
assert_throws(new TypeError(), () => {
|
||||
element.style = "color: green";
|
||||
});
|
||||
}, "TypeError when getter of [PutForwards] attribute returns non-object");
|
||||
</script>
|
|
@ -0,0 +1,131 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Sequence conversion</title>
|
||||
<link rel="help" href="https://heycam.github.io/webidl/#es-sequence">
|
||||
<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<canvas></canvas>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
const canvas = document.querySelector("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
test(() => {
|
||||
ctx.setLineDash([1, 2]);
|
||||
assert_array_equals(ctx.getLineDash(), [1, 2]);
|
||||
}, "An array");
|
||||
|
||||
test(() => {
|
||||
function* generatorFunc() {
|
||||
yield 4;
|
||||
yield 5;
|
||||
}
|
||||
const generator = generatorFunc();
|
||||
|
||||
ctx.setLineDash(generator);
|
||||
assert_array_equals(ctx.getLineDash(), [4, 5]);
|
||||
}, "A generator");
|
||||
|
||||
test(() => {
|
||||
function* generatorFunc() {
|
||||
yield 6;
|
||||
yield 7;
|
||||
}
|
||||
|
||||
let callCount = 0;
|
||||
const array = [1, 2];
|
||||
Object.defineProperty(array, Symbol.iterator, {
|
||||
get() {
|
||||
++callCount;
|
||||
return generatorFunc;
|
||||
}
|
||||
});
|
||||
|
||||
ctx.setLineDash(array);
|
||||
assert_array_equals(ctx.getLineDash(), [6, 7]);
|
||||
assert_equals(callCount, 1, "@@iterator must only have been gotten once");
|
||||
}, "An array with an overridden Symbol.iterator");
|
||||
|
||||
test(t => {
|
||||
const originalIterator = Object.getOwnPropertyDescriptor(Array.prototype, Symbol.iterator);
|
||||
t.add_cleanup(() => {
|
||||
Object.defineProperty(Array.prototype, Symbol.iterator, originalIterator);
|
||||
});
|
||||
|
||||
function* generatorFunc() {
|
||||
yield 11;
|
||||
yield 12;
|
||||
}
|
||||
|
||||
let callCount = 0;
|
||||
const array = [1, 2];
|
||||
Object.defineProperty(Array.prototype, Symbol.iterator, {
|
||||
get() {
|
||||
++callCount;
|
||||
return generatorFunc;
|
||||
}
|
||||
});
|
||||
|
||||
ctx.setLineDash(array);
|
||||
assert_array_equals(ctx.getLineDash(), [11, 12]);
|
||||
assert_equals(callCount, 1, "@@iterator must only have been gotten once");
|
||||
}, "An array with an overridden Symbol.iterator on the prototype");
|
||||
|
||||
test(t => {
|
||||
const arrayIteratorPrototype = Object.getPrototypeOf(Array.prototype[Symbol.iterator]());
|
||||
const nextBefore = arrayIteratorPrototype.next;
|
||||
t.add_cleanup(() => {
|
||||
arrayIteratorPrototype.next = nextBefore;
|
||||
});
|
||||
|
||||
let callCount = 0;
|
||||
arrayIteratorPrototype.next = () => {
|
||||
switch (callCount) {
|
||||
case 0: {
|
||||
++callCount;
|
||||
return { done: false, value: 8 };
|
||||
}
|
||||
case 1: {
|
||||
++callCount;
|
||||
return { done: false, value: 9 };
|
||||
}
|
||||
case 2: {
|
||||
++callCount;
|
||||
return { done: true, value: 10 }; // value should be ignored this time
|
||||
}
|
||||
default: {
|
||||
assert_unreached("next() should be called three times exactly");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const array = [1, 2];
|
||||
ctx.setLineDash(array);
|
||||
assert_array_equals(ctx.getLineDash(), [8, 9]);
|
||||
assert_equals(callCount, 3, "next() must have been called thrice");
|
||||
}, "An array with an overridden %ArrayIterator%.prototype.next");
|
||||
|
||||
test(t => {
|
||||
t.add_cleanup(() => {
|
||||
delete Array.prototype[1];
|
||||
});
|
||||
|
||||
Object.defineProperty(Array.prototype, "1", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
return 14;
|
||||
}
|
||||
});
|
||||
|
||||
const array = [13, , 15, 16];
|
||||
ctx.setLineDash(array);
|
||||
assert_array_equals(ctx.getLineDash(), [13, 14, 15, 16]);
|
||||
}, "A holey array with fallback to an accessor on the prototype");
|
||||
|
||||
</script>
|
|
@ -0,0 +1 @@
|
|||
<base xmlns="http://www.w3.org/1999/xhtml" href="https://example.com/"/>
|
|
@ -4,8 +4,6 @@
|
|||
<title>XMLHttpRequest: responseXML document properties</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://xhr.spec.whatwg.org/#the-responsexml-attribute" data-tested-assertations="following::ol[1]/li[4]" />
|
||||
<link rel="help" href="https://xhr.spec.whatwg.org/#document-response-entity-body" data-tested-assertations="following::ol[1]/li[6] following::ol[1]/li[7] following::ol[1]/li[8] following::ol[1]/li[10]" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
|
@ -14,10 +12,12 @@
|
|||
var client = new XMLHttpRequest()
|
||||
client.open("GET", "resources/well-formed.xml", false)
|
||||
client.send(null)
|
||||
var responseURL = new URL('resources/well-formed.xml', location.href).href
|
||||
var expected = {
|
||||
domain:undefined,
|
||||
URL:location.href.replace(/[^/]*$/, 'resources/well-formed.xml'),
|
||||
documentURI:location.href.replace(/[^/]*$/, 'resources/well-formed.xml'),
|
||||
URL:responseURL,
|
||||
documentURI:responseURL,
|
||||
baseURI:responseURL,
|
||||
referrer:'',
|
||||
title:'',
|
||||
contentType:'application/xml',
|
||||
|
@ -43,6 +43,38 @@
|
|||
}, name)
|
||||
}
|
||||
|
||||
async_test(t => {
|
||||
const client = new XMLHttpRequest();
|
||||
client.open("GET", "resources/redirect.py?location=well-formed.xml");
|
||||
client.send();
|
||||
client.onload = t.step_func_done(() => {
|
||||
assert_equals(client.responseXML.URL, responseURL);
|
||||
assert_equals(client.responseXML.baseURI, responseURL);
|
||||
});
|
||||
}, "Test document URL properties after redirect");
|
||||
|
||||
async_test(t => {
|
||||
const client = new XMLHttpRequest();
|
||||
client.open("GET", "resources/redirect.py?location=base.xml");
|
||||
client.send();
|
||||
client.onload = t.step_func_done(() => {
|
||||
const localResponseURL = new URL('resources/base.xml', location.href).href;
|
||||
assert_equals(client.responseXML.URL, localResponseURL);
|
||||
assert_equals(client.responseXML.baseURI, 'https://example.com/');
|
||||
client.responseXML.documentElement.remove();
|
||||
assert_equals(client.responseXML.baseURI, localResponseURL);
|
||||
const newBase = document.createElement("base"),
|
||||
newBaseURL = "https://elsewhere.example/";
|
||||
newBase.href = "https://elsewhere.example/";
|
||||
client.responseXML.appendChild(newBase);
|
||||
assert_equals(client.responseXML.baseURI, newBaseURL);
|
||||
newBase.remove();
|
||||
document.head.appendChild(newBase);
|
||||
assert_equals(client.responseXML.baseURI, localResponseURL);
|
||||
newBase.remove();
|
||||
});
|
||||
}, "Test document URL properties of document with <base> after redirect");
|
||||
|
||||
test(function() {
|
||||
var lastModified = Math.floor(new Date(client.responseXML.lastModified).getTime() / 1000);
|
||||
var now = Math.floor(new Date().getTime(new Date().getTime() + 3000) / 1000); // three seconds from now, in case there's clock drift
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: battery neither empty or full, charger plugged in</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<meta name="flags" content="interact">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: battery neither empty or full, charger unplugged in</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<meta name="flags" content="interact">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: battery full, charger plugged in</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<meta name="flags" content="interact">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: navigator.getBattery() is not allowed in non top-level browsing context</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<iframe id="blank" src="about:blank" style="display: none"></iframe>
|
||||
<script>
|
||||
|
||||
function load_iframe(iframe, src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
iframe.onload = () => resolve(iframe);
|
||||
iframe.src = src;
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(t => {
|
||||
var iframe = document.getElementById('blank');
|
||||
var src = 'support-iframe.html';
|
||||
return load_iframe(iframe, src)
|
||||
.then(iframe => promise_rejects(t, 'SecurityError',
|
||||
iframe.contentWindow.navigator.getBattery()));
|
||||
}, "throw a 'SecurityError' when invoking navigator.getBattery() within iframe");
|
||||
|
||||
</script>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: navigator.getBattery() shall throw "SecurityError" in an insecure context</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
#note {
|
||||
background-color: #fef1b5;
|
||||
border: solid 1px #cdab2d;
|
||||
padding: 5px;
|
||||
margin: 15px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<div id="note">
|
||||
Run test in an insecure context, e.g. http://example.com/.
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
promise_test(t => {
|
||||
return promise_rejects(t, 'SecurityError', navigator.getBattery());
|
||||
}, "navigator.getBattery() shall throw a 'SecurityError' in an insecure context");
|
||||
|
||||
</script>
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery test: IDL</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/WebIDLParser.js"></script>
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: battery not full, charger plugging in</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<meta name="flags" content="interact">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
|
@ -1,80 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: iframe has a different Navigator object</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
iframe {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<div id="log"></div>
|
||||
<iframe id="blank" src="about:blank"></iframe>
|
||||
<iframe id="frame"></iframe>
|
||||
<script>
|
||||
promise_test(function(t) {
|
||||
var iframe = document.querySelector('#blank');
|
||||
var originalPromise = navigator.getBattery();
|
||||
|
||||
return originalPromise.then(function(originalManager) {
|
||||
var promise = iframe.contentWindow.navigator.getBattery();
|
||||
|
||||
assert_true(originalManager instanceof BatteryManager);
|
||||
assert_not_equals(iframe.contentWindow.navigator,
|
||||
navigator,
|
||||
'navigator objects shall be different');
|
||||
assert_not_equals(promise,
|
||||
originalPromise,
|
||||
'battery promises in different navigators shall be different');
|
||||
assert_equals(iframe.contentWindow.navigator.getBattery(),
|
||||
promise,
|
||||
'battery promises in same navigator shall be same');
|
||||
|
||||
return promise;
|
||||
}).then(function(manager) {
|
||||
assert_equals(manager.__proto__,
|
||||
iframe.contentWindow.BatteryManager.prototype);
|
||||
assert_true(manager instanceof iframe.contentWindow.BatteryManager);
|
||||
});
|
||||
|
||||
}, 'iframe has a different Navigator object thus getting another battery promise');
|
||||
|
||||
async_test(function (t) {
|
||||
var iframe = document.querySelector('#blank');
|
||||
var originalNavigator = iframe.contentWindow.navigator;
|
||||
var originalPromise = iframe.contentWindow.navigator.getBattery();
|
||||
|
||||
iframe.onload = t.step_func(function() {
|
||||
assert_equals(iframe.contentWindow.navigator,
|
||||
originalNavigator,
|
||||
'navigator objects shall be same');
|
||||
assert_equals(iframe.contentWindow.navigator.getBattery(),
|
||||
originalPromise,
|
||||
'battery status promises shall be same');
|
||||
t.done();
|
||||
});
|
||||
|
||||
iframe.src = 'support-iframe.html';
|
||||
}, 'setting src of an iframe with initial about:blank makes same Navigator object and battery promise');
|
||||
|
||||
async_test(function (t) {
|
||||
var iframe = document.querySelector('#frame');
|
||||
iframe.src = 'support-iframe-initial.html';
|
||||
iframe.onload = t.step_func(function() {
|
||||
var originalNavigator = iframe.contentWindow.navigator;
|
||||
var originalPromise = iframe.contentWindow.navigator.getBattery();
|
||||
|
||||
iframe.onload = t.step_func(function() {
|
||||
assert_not_equals(iframe.contentWindow.navigator,
|
||||
originalNavigator,
|
||||
'navigator objects shall be changed');
|
||||
assert_not_equals(iframe.contentWindow.navigator.getBattery(),
|
||||
originalPromise,
|
||||
'battery status promises shall be different');
|
||||
t.done();
|
||||
});
|
||||
|
||||
iframe.src = 'support-iframe.html';
|
||||
});
|
||||
}, 'setting src of an iframe with initial frame makes its Navigator object vary thus getting another battery promise');
|
||||
</script>
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: window.open() makes a different Navigator object</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
|
@ -1,7 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: navigator.getBattery() always return same battery promise</title>
|
||||
<link rel="author" title="YuichiNukiyama" href="https://github.com/YuichiNukiyama">
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Battery Test: charger unplugging</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/battery-status/">
|
||||
<meta name="flags" content="interact">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
|
@ -1,5 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset="utf-8">
|
||||
<div>
|
||||
Hello!
|
||||
</div>
|
|
@ -33,6 +33,7 @@ wptrunner_root = None
|
|||
|
||||
logger = None
|
||||
|
||||
|
||||
def do_delayed_imports():
|
||||
"""Import and set up modules only needed if execution gets to this point."""
|
||||
global BaseHandler
|
||||
|
@ -189,6 +190,9 @@ class Firefox(Browser):
|
|||
binary = "%s/firefox/firefox"
|
||||
platform_ini = "%s/firefox/platform.ini"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
pass
|
||||
|
||||
def install(self):
|
||||
"""Install Firefox."""
|
||||
call("pip", "install", "-r", os.path.join(wptrunner_root, "requirements_firefox.txt"))
|
||||
|
@ -259,6 +263,9 @@ class Chrome(Browser):
|
|||
product = "chrome"
|
||||
binary = "/usr/bin/google-chrome"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
pass
|
||||
|
||||
def install(self):
|
||||
"""Install Chrome."""
|
||||
|
||||
|
@ -310,6 +317,53 @@ class Chrome(Browser):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
class Sauce(Browser):
|
||||
"""Sauce-specific interface.
|
||||
|
||||
Includes installation and wptrunner setup methods.
|
||||
"""
|
||||
|
||||
product = "sauce"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
browser = kwargs["product"].split(":")
|
||||
self.browser_name = browser[1]
|
||||
self.browser_version = browser[2]
|
||||
self.sauce_platform = kwargs["sauce_platform"]
|
||||
self.sauce_build = kwargs["sauce_build_number"]
|
||||
self.sauce_key = kwargs["sauce_key"]
|
||||
self.sauce_user = kwargs["sauce_user"]
|
||||
self.sauce_build_tags = kwargs["sauce_build_tags"]
|
||||
self.sauce_tunnel_id = kwargs["sauce_tunnel_identifier"]
|
||||
|
||||
def install(self):
|
||||
"""Install sauce selenium python deps."""
|
||||
call("pip", "install", "-r", os.path.join(wptrunner_root, "requirements_sauce.txt"))
|
||||
|
||||
def install_webdriver(self):
|
||||
"""No need to install webdriver locally."""
|
||||
pass
|
||||
|
||||
def version(self, root):
|
||||
"""Retrieve the release version of the browser under test."""
|
||||
return self.browser_version
|
||||
|
||||
def wptrunner_args(self, root):
|
||||
"""Return Sauce-specific wptrunner arguments."""
|
||||
return {
|
||||
"product": "sauce",
|
||||
"sauce_browser": self.browser_name,
|
||||
"sauce_build": self.sauce_build,
|
||||
"sauce_key": self.sauce_key,
|
||||
"sauce_platform": self.sauce_platform,
|
||||
"sauce_tags": self.sauce_build_tags,
|
||||
"sauce_tunnel_id": self.sauce_tunnel_id,
|
||||
"sauce_user": self.sauce_user,
|
||||
"sauce_version": self.browser_version,
|
||||
"test_types": ["testharness", "reftest"]
|
||||
}
|
||||
|
||||
|
||||
def get(url):
|
||||
"""Issue GET request to a given URL and return the response."""
|
||||
logger.debug("GET %s" % url)
|
||||
|
@ -486,9 +540,19 @@ def get_files_changed(branch_point, ignore_changes):
|
|||
|
||||
return changed, ignored
|
||||
|
||||
|
||||
def _in_repo_root(full_path):
|
||||
rel_path = os.path.relpath(full_path, wpt_root)
|
||||
path_components = rel_path.split(os.sep)
|
||||
return len(path_components) < 2
|
||||
|
||||
|
||||
def get_affected_testfiles(files_changed, skip_tests):
|
||||
"""Determine and return list of test files that reference changed files."""
|
||||
affected_testfiles = set()
|
||||
# Exclude files that are in the repo root, because
|
||||
# they are not part of any test.
|
||||
files_changed = [f for f in files_changed if not _in_repo_root(f)]
|
||||
nontests_changed = set(files_changed)
|
||||
manifest_file = os.path.join(wpt_root, "MANIFEST.json")
|
||||
test_types = ["testharness", "reftest", "wdspec"]
|
||||
|
@ -497,6 +561,8 @@ def get_affected_testfiles(files_changed, skip_tests):
|
|||
|
||||
support_files = {os.path.join(wpt_root, path)
|
||||
for _, path, _ in wpt_manifest.itertypes("support")}
|
||||
wdspec_test_files = {os.path.join(wpt_root, path)
|
||||
for _, path, _ in wpt_manifest.itertypes("wdspec")}
|
||||
test_files = {os.path.join(wpt_root, path)
|
||||
for _, path, _ in wpt_manifest.itertypes(*test_types)}
|
||||
|
||||
|
@ -506,19 +572,30 @@ def get_affected_testfiles(files_changed, skip_tests):
|
|||
for full_path in nontests_changed:
|
||||
rel_path = os.path.relpath(full_path, wpt_root)
|
||||
path_components = rel_path.split(os.sep)
|
||||
if len(path_components) < 2:
|
||||
# This changed file is in the repo root, so skip it
|
||||
# (because it's not part of any test).
|
||||
continue
|
||||
top_level_subdir = path_components[0]
|
||||
if top_level_subdir in skip_tests:
|
||||
continue
|
||||
repo_path = "/" + os.path.relpath(full_path, wpt_root).replace(os.path.sep, "/")
|
||||
nontest_changed_paths.add((full_path, repo_path))
|
||||
|
||||
def affected_by_wdspec(test):
|
||||
affected = False
|
||||
if test in wdspec_test_files:
|
||||
for support_full_path, _ in nontest_changed_paths:
|
||||
# parent of support file or of "support" directory
|
||||
parent = os.path.dirname(support_full_path)
|
||||
if os.path.basename(parent) == "support":
|
||||
parent = os.path.dirname(parent)
|
||||
relpath = os.path.relpath(test, parent)
|
||||
if not relpath.startswith(os.pardir):
|
||||
# testfile is in subtree of support file
|
||||
affected = True
|
||||
break
|
||||
return affected
|
||||
|
||||
for root, dirs, fnames in os.walk(wpt_root):
|
||||
# Walk top_level_subdir looking for test files containing either the
|
||||
# relative filepath or absolute filepatch to the changed files.
|
||||
# relative filepath or absolute filepath to the changed files.
|
||||
if root == wpt_root:
|
||||
for dir_name in skip_tests:
|
||||
dirs.remove(dir_name)
|
||||
|
@ -527,6 +604,10 @@ def get_affected_testfiles(files_changed, skip_tests):
|
|||
# Skip any file that's not a test file.
|
||||
if test_full_path not in test_files:
|
||||
continue
|
||||
if affected_by_wdspec(test_full_path):
|
||||
affected_testfiles.add(test_full_path)
|
||||
continue
|
||||
|
||||
with open(test_full_path, "rb") as fh:
|
||||
file_contents = fh.read()
|
||||
if file_contents.startswith("\xfe\xff"):
|
||||
|
@ -655,7 +736,7 @@ def format_comment_title(product):
|
|||
title = parts[0].title()
|
||||
|
||||
if len(parts) > 1:
|
||||
title += " (%s channel)" % parts[1]
|
||||
title += " (%s)" % parts[1]
|
||||
|
||||
return "# %s #" % title
|
||||
|
||||
|
@ -686,6 +767,7 @@ def table(headings, data, log):
|
|||
log("|%s|" % "|".join(" %s" % row[i].ljust(max_widths[i] - 1) for i in cols))
|
||||
log("")
|
||||
|
||||
|
||||
def write_inconsistent(inconsistent, iterations):
|
||||
"""Output inconsistent tests to logger.error."""
|
||||
logger.error("## Unstable results ##\n")
|
||||
|
@ -772,6 +854,30 @@ def get_parser():
|
|||
type=str,
|
||||
help="Location of ini-formatted configuration file",
|
||||
default="check_stability.ini")
|
||||
parser.add_argument("--sauce-platform",
|
||||
action="store",
|
||||
default=os.environ.get("PLATFORM"),
|
||||
help="Sauce Labs OS")
|
||||
parser.add_argument("--sauce-build-number",
|
||||
action="store",
|
||||
default=os.environ.get("TRAVIS_BUILD_NUMBER"),
|
||||
help="Sauce Labs build identifier")
|
||||
parser.add_argument("--sauce-build-tags",
|
||||
action="store", nargs="*",
|
||||
default=[os.environ.get("TRAVIS_PYTHON_VERSION")],
|
||||
help="Sauce Labs build tag")
|
||||
parser.add_argument("--sauce-tunnel-identifier",
|
||||
action="store",
|
||||
default=os.environ.get("TRAVIS_JOB_NUMBER"),
|
||||
help="Sauce Connect tunnel identifier")
|
||||
parser.add_argument("--sauce-user",
|
||||
action="store",
|
||||
default=os.environ.get("SAUCE_USERNAME"),
|
||||
help="Sauce Labs user name")
|
||||
parser.add_argument("--sauce-key",
|
||||
action="store",
|
||||
default=os.environ.get("SAUCE_ACCESS_KEY"),
|
||||
help="Sauce Labs access key")
|
||||
parser.add_argument("product",
|
||||
action="store",
|
||||
help="Product to run against (`browser-name` or 'browser-name:channel')")
|
||||
|
@ -809,14 +915,18 @@ def main():
|
|||
return 1
|
||||
|
||||
os.chdir(args.root)
|
||||
|
||||
browser_name = args.product.split(":")[0]
|
||||
|
||||
if browser_name == "sauce" and not args.sauce_key:
|
||||
logger.warning("Cannot run tests on Sauce Labs. No access key.")
|
||||
return retcode
|
||||
|
||||
with TravisFold("browser_setup"):
|
||||
logger.info(format_comment_title(args.product))
|
||||
|
||||
browser_cls = {"firefox": Firefox,
|
||||
"chrome": Chrome}.get(browser_name)
|
||||
"chrome": Chrome,
|
||||
"sauce": Sauce}.get(browser_name)
|
||||
if browser_cls is None:
|
||||
logger.critical("Unrecognised browser %s" % browser_name)
|
||||
return 1
|
||||
|
@ -844,7 +954,7 @@ def main():
|
|||
install_wptrunner()
|
||||
do_delayed_imports()
|
||||
|
||||
browser = browser_cls()
|
||||
browser = browser_cls(**vars(args))
|
||||
browser.install()
|
||||
browser.install_webdriver()
|
||||
|
||||
|
|
|
@ -1985,9 +1985,9 @@
|
|||
"html/elements/style/scoped-novalid.html": "Element \u201cstyle\u201d not allowed in this context. (The parent was element \u201cdiv\u201d.) Suppressing further errors from this subtree.",
|
||||
"html/elements/sub/model-novalid.html": "End tag \u201cp\u201d implied, but there were open elements.",
|
||||
"html/elements/sup/model-novalid.html": "End tag \u201cp\u201d implied, but there were open elements.",
|
||||
"html/elements/table/integrity/Alexis_of_Russia-novalid.html": "The \u201calign\u201d attribute on the \u201ctable\u201d element is obsolete. Use CSS instead.",
|
||||
"html/elements/table/integrity/Feodor_I_of_Russia-novalid.html": "The \u201calign\u201d attribute on the \u201ctable\u201d element is obsolete. Use CSS instead.",
|
||||
"html/elements/table/integrity/Naser_al-Din_Shah_Qajar-novalid.html": "An \u201cimg\u201d element must have an \u201calt\u201d attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.",
|
||||
"html/elements/table/integrity/Alexis_of_Russia-novalid.html": "Bad value \u201ccopyright\u201d for attribute \u201crel\u201d on element \u201clink\u201d: Bad list of link-type keywords: The keyword \u201ccopyright\u201d for the \u201crel\u201d attribute should not be used. Consider using \u201clicense\u201d instead.",
|
||||
"html/elements/table/integrity/Feodor_I_of_Russia-novalid.html": "Bad value \u201ccopyright\u201d for attribute \u201crel\u201d on element \u201clink\u201d: Bad list of link-type keywords: The keyword \u201ccopyright\u201d for the \u201crel\u201d attribute should not be used. Consider using \u201clicense\u201d instead.",
|
||||
"html/elements/table/integrity/Naser_al-Din_Shah_Qajar-novalid.html": "Bad value \u201ccopyright\u201d for attribute \u201crel\u201d on element \u201clink\u201d: Bad list of link-type keywords: The keyword \u201ccopyright\u201d for the \u201crel\u201d attribute should not be used. Consider using \u201clicense\u201d instead.",
|
||||
"html/elements/table/integrity/vertical-novalid.html": "Table cell is overlapped by later table cell.",
|
||||
"html/elements/table/model-input-child-hidden-novalid.html": "Start tag \u201cinput\u201d seen in \u201ctable\u201d.",
|
||||
"html/elements/table/model-input-child-novalid.html": "Start tag \u201cinput\u201d seen in \u201ctable\u201d.",
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<meta http-equiv="content-security-policy" content="script-src 'nonce-abc'; img-src 'none'">
|
||||
|
||||
<body>
|
||||
<!-- Basics -->
|
||||
<script nonce="abc" id="testScript">
|
||||
document.currentScript.setAttribute('executed', 'yay');
|
||||
</script>
|
||||
|
||||
<script nonce="abc">
|
||||
var script = document.querySelector('#testScript');
|
||||
|
||||
test(t => {
|
||||
// Query Selector
|
||||
assert_equals(document.querySelector('body [nonce]'), script);
|
||||
assert_equals(document.querySelector('body [nonce=""]'), null);
|
||||
assert_equals(document.querySelector('body [nonce=abc]'), script);
|
||||
|
||||
assert_equals(script.getAttribute('nonce'), 'abc');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Reading 'nonce' content attribute and IDL attribute.");
|
||||
|
||||
// Clone node.
|
||||
test(t => {
|
||||
script.setAttribute('executed', 'boo');
|
||||
var s2 = script.cloneNode();
|
||||
assert_equals(s2.nonce, 'abc', 'IDL attribute');
|
||||
assert_equals(s2.getAttribute('nonce'), 'abc');
|
||||
}, "Cloned node retains nonce.");
|
||||
|
||||
async_test(t => {
|
||||
var s2 = script.cloneNode();
|
||||
document.head.appendChild(s2);
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(s2.nonce, 'abc');
|
||||
assert_equals(s2.getAttribute('nonce'), 'abc');
|
||||
|
||||
// The cloned script won't execute, as its 'already started' flag is set.
|
||||
assert_equals(s2.getAttribute('executed'), 'boo');
|
||||
}));
|
||||
}, "Cloned node retains nonce when inserted.");
|
||||
|
||||
// Set the content attribute to 'foo'
|
||||
test(t => {
|
||||
script.setAttribute('nonce', 'foo');
|
||||
assert_equals(script.getAttribute('nonce'), 'foo');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Writing 'nonce' content attribute.");
|
||||
|
||||
// Set the IDL attribute to 'bar'
|
||||
test(t => {
|
||||
script.nonce = 'bar';
|
||||
assert_equals(script.nonce, 'bar');
|
||||
assert_equals(script.getAttribute('nonce'), 'foo');
|
||||
}, "Writing 'nonce' IDL attribute.");
|
||||
|
||||
// Fragment parser.
|
||||
var documentWriteTest = async_test("Document-written script executes.");
|
||||
document.write(`<script nonce='abc'>
|
||||
documentWriteTest.done();
|
||||
test(t => {
|
||||
var script = document.currentScript;
|
||||
assert_equals(script.getAttribute('nonce'), 'abc');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Document-written script's nonce value.");
|
||||
</scr` + `ipt>`);
|
||||
|
||||
// Create node.
|
||||
async_test(t => {
|
||||
var s = document.createElement('script');
|
||||
s.innerText = script.innerText;
|
||||
s.nonce = 'abc';
|
||||
document.head.appendChild(s);
|
||||
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(s.nonce, 'abc');
|
||||
assert_equals(s.getAttribute('nonce'), null);
|
||||
assert_equals(s.getAttribute('executed'), 'yay');
|
||||
}));
|
||||
}, "createElement.nonce.");
|
||||
|
||||
// Create node.
|
||||
async_test(t => {
|
||||
var s = document.createElement('script');
|
||||
s.innerText = script.innerText;
|
||||
s.setAttribute('nonce', 'abc');
|
||||
assert_equals(s.getAttribute('nonce'), 'abc', "Pre-insertion content");
|
||||
assert_equals(s.nonce, '', "Pre-insertion IDL");
|
||||
document.head.appendChild(s);
|
||||
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(s.nonce, 'abc', "Post-insertion IDL");
|
||||
assert_equals(s.getAttribute('nonce'), 'abc', "Post-insertion content");
|
||||
assert_equals(s.getAttribute('executed'), 'yay');
|
||||
}));
|
||||
}, "createElement.setAttribute.");
|
||||
</script>
|
||||
|
||||
<!-- CSS Leakage -->
|
||||
<style>
|
||||
#cssTest { display: block; }
|
||||
#cssTest[nonce=abc] { background: url(/security/resources/abe.png); }
|
||||
</style>
|
||||
<script nonce="abc" id="cssTest">
|
||||
async_test(t => {
|
||||
requestAnimationFrame(t.step_func_done(_ => {
|
||||
var script = document.querySelector('#cssTest');
|
||||
var style = getComputedStyle(script);
|
||||
assert_equals(style['display'], 'block');
|
||||
assert_equals(style['background-image'], "url(\"http://web-platform.test:8001/security/resources/abe.png\")");
|
||||
}));
|
||||
}, "Nonces leak via CSS side-channels.");
|
||||
</script>
|
|
@ -0,0 +1,114 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js" nonce="abc"></script>
|
||||
<script src="/resources/testharnessreport.js" nonce="abc"></script>
|
||||
|
||||
<!-- `Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'` delivered via headers -->
|
||||
|
||||
<body>
|
||||
<!-- Basics -->
|
||||
<script nonce="abc" id="testScript">
|
||||
document.currentScript.setAttribute('executed', 'yay');
|
||||
</script>
|
||||
|
||||
<script nonce="abc">
|
||||
var script = document.querySelector('#testScript');
|
||||
|
||||
test(t => {
|
||||
// Query Selector
|
||||
assert_equals(document.querySelector('body [nonce]'), script);
|
||||
assert_equals(document.querySelector('body [nonce=""]'), script);
|
||||
assert_equals(document.querySelector('body [nonce=abc]'), null);
|
||||
|
||||
assert_equals(script.getAttribute('nonce'), '');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Reading 'nonce' content attribute and IDL attribute.");
|
||||
|
||||
// Clone node.
|
||||
test(t => {
|
||||
script.setAttribute('executed', 'boo');
|
||||
var s2 = script.cloneNode();
|
||||
assert_equals(s2.nonce, 'abc', 'IDL attribute');
|
||||
assert_equals(s2.getAttribute('nonce'), '');
|
||||
}, "Cloned node retains nonce.");
|
||||
|
||||
async_test(t => {
|
||||
var s2 = script.cloneNode();
|
||||
document.head.appendChild(s2);
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(s2.nonce, 'abc');
|
||||
assert_equals(s2.getAttribute('nonce'), '');
|
||||
|
||||
// The cloned script won't execute, as its 'already started' flag is set.
|
||||
assert_equals(s2.getAttribute('executed'), 'boo');
|
||||
}));
|
||||
}, "Cloned node retains nonce when inserted.");
|
||||
|
||||
// Set the content attribute to 'foo'
|
||||
test(t => {
|
||||
script.setAttribute('nonce', 'foo');
|
||||
assert_equals(script.getAttribute('nonce'), 'foo');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Writing 'nonce' content attribute.");
|
||||
|
||||
// Set the IDL attribute to 'bar'
|
||||
test(t => {
|
||||
script.nonce = 'bar';
|
||||
assert_equals(script.nonce, 'bar');
|
||||
assert_equals(script.getAttribute('nonce'), 'foo');
|
||||
}, "Writing 'nonce' IDL attribute.");
|
||||
|
||||
// Fragment parser.
|
||||
var documentWriteTest = async_test("Document-written script executes.");
|
||||
document.write(`<script nonce='abc'>
|
||||
documentWriteTest.done();
|
||||
test(t => {
|
||||
var script = document.currentScript;
|
||||
assert_equals(script.getAttribute('nonce'), '');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Document-written script's nonce value.");
|
||||
</scr` + `ipt>`);
|
||||
|
||||
// Create node.
|
||||
async_test(t => {
|
||||
var s = document.createElement('script');
|
||||
s.innerText = script.innerText;
|
||||
s.nonce = 'abc';
|
||||
document.head.appendChild(s);
|
||||
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(s.nonce, 'abc');
|
||||
assert_equals(s.getAttribute('nonce'), null);
|
||||
}));
|
||||
}, "createElement.nonce.");
|
||||
|
||||
// Create node.
|
||||
async_test(t => {
|
||||
var s = document.createElement('script');
|
||||
s.innerText = script.innerText;
|
||||
s.setAttribute('nonce', 'abc');
|
||||
assert_equals(s.getAttribute('nonce'), 'abc', "Pre-insertion content");
|
||||
assert_equals(s.nonce, '', "Pre-insertion IDL");
|
||||
document.head.appendChild(s);
|
||||
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(s.nonce, 'abc', "Post-insertion IDL");
|
||||
assert_equals(s.getAttribute('nonce'), '', "Post-insertion content");
|
||||
}));
|
||||
}, "createElement.setAttribute.");
|
||||
</script>
|
||||
|
||||
<!-- CSS Leakage -->
|
||||
<style>
|
||||
#cssTest { display: block; }
|
||||
#cssTest[nonce=abc] { background: url(/security/resources/abe.png); }
|
||||
</style>
|
||||
<script nonce="abc" id="cssTest">
|
||||
async_test(t => {
|
||||
requestAnimationFrame(t.step_func_done(_ => {
|
||||
var script = document.querySelector('#cssTest');
|
||||
var style = getComputedStyle(script);
|
||||
assert_equals(style['display'], 'block');
|
||||
assert_equals(style['background-image'], 'none');
|
||||
}));
|
||||
}, "Nonces don't leak via CSS side-channels.");
|
||||
</script>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'
|
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<meta http-equiv="content-security-policy" content="script-src 'nonce-abc'; img-src 'none'">
|
||||
|
||||
<body>
|
||||
<!-- Basics -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<script nonce="abc" id="testScript">
|
||||
document.currentScript.setAttribute('executed', 'yay');
|
||||
</script>
|
||||
</svg>
|
||||
|
||||
<script nonce="abc">
|
||||
var script = document.querySelector('#testScript');
|
||||
|
||||
test(t => {
|
||||
// Query Selector
|
||||
assert_equals(document.querySelector('[nonce]'), script);
|
||||
assert_equals(document.querySelector('[nonce=""]'), null);
|
||||
assert_equals(document.querySelector('[nonce=abc]'), script);
|
||||
|
||||
assert_equals(script.getAttribute('nonce'), 'abc');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Reading 'nonce' content attribute and IDL attribute.");
|
||||
|
||||
// Clone node.
|
||||
test(t => {
|
||||
script.setAttribute('executed', 'boo');
|
||||
var s2 = script.cloneNode();
|
||||
assert_equals(s2.nonce, 'abc', 'IDL attribute');
|
||||
assert_equals(s2.getAttribute('nonce'), 'abc');
|
||||
}, "Cloned node retains nonce.");
|
||||
|
||||
async_test(t => {
|
||||
var s2 = script.cloneNode();
|
||||
document.head.appendChild(s2);
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(s2.nonce, 'abc');
|
||||
assert_equals(s2.getAttribute('nonce'), 'abc');
|
||||
|
||||
// The cloned script won't execute, as its 'already started' flag is set.
|
||||
assert_equals(s2.getAttribute('executed'), 'boo');
|
||||
}));
|
||||
}, "Cloned node retains nonce when inserted.");
|
||||
|
||||
// Set the content attribute to 'foo'
|
||||
test(t => {
|
||||
script.setAttribute('nonce', 'foo');
|
||||
assert_equals(script.getAttribute('nonce'), 'foo');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Writing 'nonce' content attribute.");
|
||||
|
||||
// Set the IDL attribute to 'bar'
|
||||
test(t => {
|
||||
script.nonce = 'bar';
|
||||
assert_equals(script.nonce, 'bar');
|
||||
assert_equals(script.getAttribute('nonce'), 'foo');
|
||||
}, "Writing 'nonce' IDL attribute.");
|
||||
|
||||
// Fragment parser.
|
||||
var documentWriteTest = async_test("Document-written script executes.");
|
||||
document.write(`<svg xmlns="http://www.w3.org/2000/svg"><script nonce='abc'>
|
||||
documentWriteTest.done();
|
||||
test(t => {
|
||||
var script = document.currentScript;
|
||||
assert_equals(script.getAttribute('nonce'), 'abc');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Document-written script's nonce value.");
|
||||
</scr` + `ipt></svg>`);
|
||||
|
||||
// Create node.
|
||||
async_test(t => {
|
||||
var s = document.createElement('svg');
|
||||
var innerScript = document.createElement('innerScript');
|
||||
innerScript.innerText = script.innerText;
|
||||
innerScript.nonce = 'abc';
|
||||
s.appendChild(innerScript);
|
||||
document.body.appendChild(s);
|
||||
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(innerScript.nonce, 'abc');
|
||||
assert_equals(innerScript.getAttribute('nonce'), null, 'innerScript.getAttribute nonce');
|
||||
}));
|
||||
}, "createElement.nonce.");
|
||||
|
||||
// Create node.
|
||||
async_test(t => {
|
||||
var s = document.createElement('svg');
|
||||
var innerScript = document.createElement('script');
|
||||
innerScript.innerText = script.innerText;
|
||||
innerScript.setAttribute('nonce', 'abc');
|
||||
assert_equals(innerScript.getAttribute('nonce'), 'abc', "Pre-insertion content");
|
||||
assert_equals(innerScript.nonce, '', "Pre-insertion IDL");
|
||||
s.appendChild(innerScript);
|
||||
document.body.appendChild(s);
|
||||
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(innerScript.nonce, 'abc', "Post-insertion IDL");
|
||||
assert_equals(innerScript.getAttribute('nonce'), 'abc', "Post-insertion content");
|
||||
}));
|
||||
}, "createElement.setAttribute.");
|
||||
</script>
|
||||
|
||||
<!-- CSS Leakage -->
|
||||
<style>
|
||||
#cssTest { display: block; }
|
||||
#cssTest[nonce=abc] { background: url(/security/resources/abe.png); }
|
||||
</style>
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<script nonce="abc" id="cssTest">
|
||||
async_test(t => {
|
||||
requestAnimationFrame(t.step_func_done(_ => {
|
||||
var script = document.querySelector('#cssTest');
|
||||
var style = getComputedStyle(script);
|
||||
assert_equals(style['display'], 'block');
|
||||
assert_equals(style['background-image'], "url(\"http://web-platform.test:8001/security/resources/abe.png\")");
|
||||
}));
|
||||
}, "Nonces don't leak via CSS side-channels.");
|
||||
</script>
|
||||
</svg>
|
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js" nonce="abc"></script>
|
||||
<script src="/resources/testharnessreport.js" nonce="abc"></script>
|
||||
|
||||
<!-- `Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'` delivered via headers -->
|
||||
|
||||
<body>
|
||||
<!-- Basics -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<script nonce="abc" id="testScript">
|
||||
document.currentScript.setAttribute('executed', 'yay');
|
||||
</script>
|
||||
</svg>
|
||||
|
||||
<script nonce="abc">
|
||||
var script = document.querySelector('#testScript');
|
||||
|
||||
test(t => {
|
||||
// Query Selector
|
||||
assert_equals(document.querySelector('body [nonce]'), script);
|
||||
assert_equals(document.querySelector('body [nonce=""]'), script);
|
||||
assert_equals(document.querySelector('body [nonce=abc]'), null);
|
||||
|
||||
assert_equals(script.getAttribute('nonce'), '');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Reading 'nonce' content attribute and IDL attribute.");
|
||||
|
||||
// Clone node.
|
||||
test(t => {
|
||||
script.setAttribute('executed', 'boo');
|
||||
var s2 = script.cloneNode();
|
||||
assert_equals(s2.nonce, 'abc', 'IDL attribute');
|
||||
assert_equals(s2.getAttribute('nonce'), '');
|
||||
}, "Cloned node retains nonce.");
|
||||
|
||||
async_test(t => {
|
||||
var s2 = script.cloneNode();
|
||||
document.head.appendChild(s2);
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(s2.nonce, 'abc');
|
||||
assert_equals(s2.getAttribute('nonce'), '');
|
||||
|
||||
// The cloned script won't execute, as its 'already started' flag is set.
|
||||
assert_equals(s2.getAttribute('executed'), 'boo');
|
||||
}));
|
||||
}, "Cloned node retains nonce when inserted.");
|
||||
|
||||
// Set the content attribute to 'foo'
|
||||
test(t => {
|
||||
script.setAttribute('nonce', 'foo');
|
||||
assert_equals(script.getAttribute('nonce'), 'foo');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Writing 'nonce' content attribute.");
|
||||
|
||||
// Set the IDL attribute to 'bar'
|
||||
test(t => {
|
||||
script.nonce = 'bar';
|
||||
assert_equals(script.nonce, 'bar');
|
||||
assert_equals(script.getAttribute('nonce'), 'foo');
|
||||
}, "Writing 'nonce' IDL attribute.");
|
||||
|
||||
// Fragment parser.
|
||||
var documentWriteTest = async_test("Document-written script executes.");
|
||||
document.write(`<svg xmlns="http://www.w3.org/2000/svg"><script nonce='abc'>
|
||||
documentWriteTest.done();
|
||||
test(t => {
|
||||
var script = document.currentScript;
|
||||
assert_equals(script.getAttribute('nonce'), '');
|
||||
assert_equals(script.nonce, 'abc');
|
||||
}, "Document-written script's nonce value.");
|
||||
</scr` + `ipt></svg>`);
|
||||
|
||||
// Create node.
|
||||
async_test(t => {
|
||||
var s = document.createElement('svg');
|
||||
var innerScript = document.createElement('script');
|
||||
innerScript.innerText = script.innerText;
|
||||
innerScript.nonce = 'abc';
|
||||
s.appendChild(innerScript);
|
||||
document.body.appendChild(s);
|
||||
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(innerScript.nonce, 'abc');
|
||||
assert_equals(innerScript.getAttribute('nonce'), null);
|
||||
}));
|
||||
}, "createElement.nonce.");
|
||||
|
||||
// Create node.
|
||||
async_test(t => {
|
||||
var s = document.createElement('svg');
|
||||
var innerScript = document.createElement('script');
|
||||
innerScript.innerText = script.innerText;
|
||||
innerScript.setAttribute('nonce', 'abc');
|
||||
assert_equals(innerScript.getAttribute('nonce'), 'abc', "Pre-insertion content");
|
||||
assert_equals(innerScript.nonce, '', "Pre-insertion IDL");
|
||||
s.appendChild(innerScript);
|
||||
document.body.appendChild(s);
|
||||
|
||||
window.addEventListener('load', t.step_func_done(_ => {
|
||||
assert_equals(innerScript.nonce, 'abc', "Post-insertion IDL");
|
||||
assert_equals(innerScript.getAttribute('nonce'), '', "Post-insertion content");
|
||||
}));
|
||||
}, "createElement.setAttribute.");
|
||||
</script>
|
||||
|
||||
<!-- CSS Leakage -->
|
||||
<style>
|
||||
#cssTest { display: block; }
|
||||
#cssTest[nonce=abc] { background: url(/security/resources/abe.png); }
|
||||
</style>
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<script nonce="abc" id="cssTest">
|
||||
async_test(t => {
|
||||
requestAnimationFrame(t.step_func_done(_ => {
|
||||
var script = document.querySelector('#cssTest');
|
||||
var style = getComputedStyle(script);
|
||||
assert_equals(style['display'], 'block');
|
||||
assert_equals(style['background-image'], 'none');
|
||||
}));
|
||||
}, "Nonces don't leak via CSS side-channels.");
|
||||
</script>
|
||||
</svg>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<meta http-equiv="Content-Security-Policy" content="frame-src 'none'">
|
||||
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var t = async_test("<iframe src='javascript:...'> not blocked by 'frame-src'");
|
||||
|
||||
var i = document.createElement('iframe');
|
||||
i.src = "javascript:window.top.t.done();";
|
||||
|
||||
document.body.appendChild(i);
|
||||
</script>
|
|
@ -22,14 +22,14 @@ var CROSSDOMAIN_URL = get_host_info().HTTP_REMOTE_ORIGIN + '/cors/resources/cors
|
|||
* Redirection with preflights.
|
||||
*/
|
||||
function preflight_failure(code) {
|
||||
var desc = 'Should throw error if preflight respond with ' + code;
|
||||
var isCodeOK = code >= 200 && code <= 299,
|
||||
descOK = isCodeOK ? 'succeed' : 'throw error',
|
||||
desc = 'Should ' + descOK + ' if preflight has status ' + code;
|
||||
async_test(desc).step(function() {
|
||||
var client = new XMLHttpRequest();
|
||||
var redirect =
|
||||
encodeURIComponent(CROSSDOMAIN_URL + 'headers=x-test&' + req_c++);
|
||||
|
||||
var isCodeOK = code >= 200 && code <= 299;
|
||||
|
||||
client.open('GET',
|
||||
CROSSDOMAIN_URL + 'headers=x-test&location=' + redirect
|
||||
+ '&code=' + code + '&preflight=' + code
|
||||
|
@ -51,11 +51,12 @@ function preflight_failure(code) {
|
|||
client.send(null);
|
||||
});
|
||||
}
|
||||
[100, 101,
|
||||
200,
|
||||
[200, 299,
|
||||
300, 301, 302, 303, 304, 305, 306, 307, 308,
|
||||
400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417,
|
||||
500, 501, 502, 503, 504, 505
|
||||
500, 501, 502, 503, 504, 505,
|
||||
680,
|
||||
790
|
||||
].forEach(preflight_failure);
|
||||
|
||||
</script>
|
||||
|
|
|
@ -14,26 +14,25 @@
|
|||
readonly attribute DOMString type;
|
||||
};
|
||||
|
||||
dictionary SiteBoundCredentialData : CredentialData {
|
||||
USVString name;
|
||||
USVString iconURL;
|
||||
};
|
||||
|
||||
[NoInterfaceObject, SecureContext]
|
||||
interface CredentialUserData {
|
||||
readonly attribute USVString name;
|
||||
readonly attribute USVString iconURL;
|
||||
};
|
||||
|
||||
dictionary PasswordCredentialData : SiteBoundCredentialData {
|
||||
USVString password;
|
||||
dictionary PasswordCredentialData : CredentialData {
|
||||
USVString name;
|
||||
USVString iconURL;
|
||||
required USVString password;
|
||||
};
|
||||
|
||||
typedef (FormData or URLSearchParams) CredentialBodyType;
|
||||
|
||||
|
||||
dictionary FederatedCredentialData : SiteBoundCredentialData {
|
||||
USVString provider;
|
||||
dictionary FederatedCredentialInit : CredentialData {
|
||||
USVString name;
|
||||
USVString iconURL;
|
||||
required USVString provider;
|
||||
DOMString protocol;
|
||||
};
|
||||
|
||||
|
@ -69,7 +68,7 @@
|
|||
};
|
||||
PasswordCredential implements CredentialUserData;
|
||||
|
||||
[Constructor(FederatedCredentialData data),
|
||||
[Constructor(FederatedCredentialInit data),
|
||||
Exposed=Window,
|
||||
SecureContext]
|
||||
interface FederatedCredential : Credential {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
"window.screen.availWidth >= 0 && window.screen.availWidth <= window.screen.width");
|
||||
test(function(){assert_true(window.screen.availHeight >= 0 && window.screen.availHeight <= window.screen.height);},
|
||||
"window.screen.availHeight >= 0 && window.screen.availHeight <= window.screen.height");
|
||||
test(function(){assert_true(window.screen.colorDepth == 0 || window.screen.colorDepth == 16 || window.screen.colorDepth == 24 || window.screen.colorDepth == 32);},
|
||||
test(function(){assert_in_array(window.screen.colorDepth, [0, 16, 24, 32]);},
|
||||
"window.screen.colorDepth == 0 || window.screen.colorDepth == 16 || window.screen.colorDepth == 24 || window.screen.colorDepth == 32");
|
||||
test(function(){assert_equals(window.screen.pixelDepth, window.screen.colorDepth);},
|
||||
"window.screen.pixelDepth must return the value returned by window.screen.colorDepth");
|
||||
|
|
|
@ -109,7 +109,7 @@ test(function() {
|
|||
assert_equals(none_element_child_video.offsetParent,null);
|
||||
assert_equals(none_element_child_audio.offsetParent,null);
|
||||
assert_equals(none_element_child_canvas.offsetParent,null);
|
||||
assert_equals(none_element_child_svg.offsetParent,null);
|
||||
assert_equals(none_element_child_svg.offsetParent,undefined);
|
||||
}, "Valid the algorithm rule of offsetParent check step 1",
|
||||
{ assert: "The offsetParent attribute algorithm rule checking passed!" }
|
||||
);
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: CSSOM StyleSheet insertRule with charset and omitted second argument</title>
|
||||
<link rel="author" title="Sendil Kumar N" href="mailto:sendilkumarn.opensource@gmail.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom/">
|
||||
<link rel="help" href="http://www.w3.org/TR/cssom-1/#the-cssrule-interface">
|
||||
<meta name="flags" content="dom">
|
||||
<script src="/resources/testharness.js" type="text/javascript"></script>
|
||||
<script src="/resources/testharnessreport.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" type="text/css" href="support/import-charset.css" id="linkElement" >
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script type="text/javascript">
|
||||
var sheet = document.getElementById("linkElement").sheet;
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 0);
|
||||
sheet.insertRule("p { color: green; }");
|
||||
assert_equals(sheet.cssRules.length, 1);
|
||||
assert_equals(sheet.cssRules.item(0).cssText, "p { color: green; }");
|
||||
}, "inserRule with charset and omitted index argument");
|
||||
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 1);
|
||||
sheet.insertRule("p { color: yellow; }", undefined);
|
||||
assert_equals(sheet.cssRules.length, 2);
|
||||
assert_equals(sheet.cssRules.item(0).cssText, "p { color: yellow; }");
|
||||
}, "insertRule with charset and undefined index argument");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: CSSOM StyleSheet insertRule with import and omitted second argument</title>
|
||||
<link rel="author" title="Sendil Kumar N" href="mailto:sendilkumarn.opensource@gmail.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom/">
|
||||
<link rel="help" href="http://www.w3.org/TR/cssom-1/#the-cssrule-interface">
|
||||
<meta name="flags" content="dom">
|
||||
<script src="/resources/testharness.js" type="text/javascript"></script>
|
||||
<script src="/resources/testharnessreport.js" type="text/javascript"></script>
|
||||
<style id="styleElement">
|
||||
@import url("support/a-green.css");
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script type="text/javascript">
|
||||
var sheet = document.getElementById("styleElement").sheet;
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 1);
|
||||
assert_throws("HierarchyRequestError", function() { sheet.insertRule("p { color: green; }"); });
|
||||
assert_equals(sheet.cssRules.length, 1);
|
||||
}, "inserRule with import and omitted index argument");
|
||||
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 1);
|
||||
assert_throws("HierarchyRequestError", function() { sheet.insertRule("p { color: yellow; }", undefined); });
|
||||
assert_equals(sheet.cssRules.length, 1);
|
||||
assert_equals(sheet.cssRules.item(0).cssText, "@import url(\"support/a-green.css\");");
|
||||
}, "insertRule with import and undefined index argument");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: CSSOM StyleSheet insertRule with namespace and omitted second argument</title>
|
||||
<link rel="author" title="Sendil Kumar N" href="mailto:sendilkumarn.opensource@gmail.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom/">
|
||||
<link rel="help" href="http://www.w3.org/TR/cssom-1/#the-cssrule-interface">
|
||||
<meta name="flags" content="dom">
|
||||
<script src="/resources/testharness.js" type="text/javascript"></script>
|
||||
<script src="/resources/testharnessreport.js" type="text/javascript"></script>
|
||||
<style id="styleElement">
|
||||
@namespace svg url(http://servo);
|
||||
@namespace url(http://servo1);
|
||||
@namespace svg url("http://servo2");
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script type="text/javascript">
|
||||
var sheet = document.getElementById("styleElement").sheet;
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 3);
|
||||
assert_throws("HierarchyRequestError", function() { sheet.insertRule("p { color: green; }"); });
|
||||
assert_equals(sheet.cssRules.length, 3);
|
||||
}, "inserRule with namespace and omitted index argument");
|
||||
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 3);
|
||||
assert_throws("HierarchyRequestError", function() { sheet.insertRule("p { color: yellow; }", undefined); });
|
||||
assert_equals(sheet.cssRules.length, 3);
|
||||
}, "insertRule with namespace and undefined index argument");
|
||||
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 3);
|
||||
sheet.insertRule("@import url(\"support/a-green.css\");");
|
||||
assert_equals(sheet.cssRules.length, 4);
|
||||
}, "inserRule with namespace and omitted index argument should insert import");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: CSSOM StyleSheet insertRule omitted second argument</title>
|
||||
<link rel="author" title="Sendil Kumar N" href="mailto:sendilkumarn.opensource@gmail.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom/">
|
||||
<link rel="help" href="http://www.w3.org/TR/cssom-1/#the-cssrule-interface">
|
||||
<meta name="flags" content="dom">
|
||||
<script src="/resources/testharness.js" type="text/javascript"></script>
|
||||
<script src="/resources/testharnessreport.js" type="text/javascript"></script>
|
||||
<style id="styleElement">
|
||||
/* An initial style rule to test where the new rule is inserted relative to this one */
|
||||
nosuchelement { color: red; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script type="text/javascript">
|
||||
var sheet = document.getElementById("styleElement").sheet;
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 1);
|
||||
sheet.insertRule("p { color: green; }");
|
||||
assert_equals(sheet.cssRules.length, 2);
|
||||
assert_equals(sheet.cssRules.item(0).cssText, "p { color: green; }");
|
||||
}, "inserRule with omitted index argument");
|
||||
|
||||
test(function() {
|
||||
assert_equals(sheet.cssRules.length, 2);
|
||||
sheet.insertRule("p { color: yellow; }", undefined);
|
||||
assert_equals(sheet.cssRules.length, 3);
|
||||
assert_equals(sheet.cssRules.item(0).cssText, "p { color: yellow; }");
|
||||
}, "insertRule with undefined index argument");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
@charset "UTF-8";
|
|
@ -66,8 +66,9 @@ href="https://www.w3.org/TR/CSS21/colors.html#background-properties" />
|
|||
</tr>
|
||||
<tr>
|
||||
<td>font</td>
|
||||
<td>Requires a specific font to be installed. (Details must be
|
||||
provided and/or the font linked to in the test description)</td>
|
||||
<td>Requires a specific font to be installed at the OS level. (A link to the
|
||||
font to be installed must be provided; this is not needed if only web
|
||||
fonts are used.)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>history</td>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Parsing and serialization of doctype internal subset</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
test(function () {
|
||||
// https://www.w3.org/TR/xml11/#sec-prolog-dtd has intSubset as part of the
|
||||
// syntax, which is not represented in the DocumentType interface. Check that
|
||||
// publicId and systemId are not affected.
|
||||
var doc = new DOMParser().parseFromString('<!DOCTYPE foo [ <!ENTITY x "y"> ]><foo>&x;</foo>', 'text/xml');
|
||||
var doctype = doc.doctype;
|
||||
assert_equals(doctype.name, 'foo', 'doctype name');
|
||||
assert_equals(doctype.publicId, '', 'doctype publicId');
|
||||
assert_equals(doctype.systemId, '', 'doctype systemId');
|
||||
// Check that document itself was parsed correctly.
|
||||
var documentElementString = new XMLSerializer().serializeToString(doc.documentElement);
|
||||
assert_equals(documentElementString, '<foo>y</foo>', 'serialized document element');
|
||||
// https://w3c.github.io/DOM-Parsing/#xml-serializing-a-documenttype-node also
|
||||
// does not have any notion of the internal subset, so also check that it
|
||||
// isn't serialized by XMLSerializer.
|
||||
var doctypeString = new XMLSerializer().serializeToString(doctype);
|
||||
assert_equals(doctypeString, '<!DOCTYPE foo>', 'serialized doctype');
|
||||
});
|
||||
</script>
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"abstract"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"acknowledgments"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"afterword"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"appendix"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -91,20 +91,6 @@
|
|||
"is",
|
||||
"backlink"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
@ -121,21 +107,7 @@
|
|||
"STATE_LINKED"
|
||||
]
|
||||
],
|
||||
"UIA" : [],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
"UIA" : []
|
||||
},
|
||||
"title" : "step 2",
|
||||
"type" : "test"
|
||||
|
|
|
@ -85,20 +85,6 @@
|
|||
"is",
|
||||
"biblioentry"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"bibliography"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -91,20 +91,6 @@
|
|||
"is",
|
||||
"biblioref"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
@ -121,21 +107,7 @@
|
|||
"STATE_LINKED"
|
||||
]
|
||||
],
|
||||
"UIA" : [],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
"UIA" : []
|
||||
},
|
||||
"title" : "step 2",
|
||||
"type" : "test"
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"chapter"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"colophon"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"conclusion"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -73,20 +73,6 @@
|
|||
"is",
|
||||
"Image"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"credit"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"credits"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"dedication"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -85,20 +85,6 @@
|
|||
"is",
|
||||
"endnote"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"endnotes"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"epigraph"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"epilogue"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"errata"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"example"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"footnote"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"foreword"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"glossary"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -91,20 +91,6 @@
|
|||
"is",
|
||||
"glossref"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
@ -121,21 +107,7 @@
|
|||
"STATE_LINKED"
|
||||
]
|
||||
],
|
||||
"UIA" : [],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
"UIA" : []
|
||||
},
|
||||
"title" : "step 2",
|
||||
"type" : "test"
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"index"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"introduction"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -91,20 +91,6 @@
|
|||
"is",
|
||||
"noteref"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
@ -121,21 +107,7 @@
|
|||
"STATE_LINKED"
|
||||
]
|
||||
],
|
||||
"UIA" : [],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
"UIA" : []
|
||||
},
|
||||
"title" : "step 2",
|
||||
"type" : "test"
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"notice"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -79,20 +79,6 @@
|
|||
"is",
|
||||
"pagebreak"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"pagelist"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"part"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"preface"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"prologue"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"pullquote"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"qna"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"subtitle"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -77,20 +77,6 @@
|
|||
"is",
|
||||
"tip"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -89,20 +89,6 @@
|
|||
"is",
|
||||
"toc"
|
||||
]
|
||||
],
|
||||
"WAIFAKE" : [
|
||||
[
|
||||
"property",
|
||||
"role",
|
||||
"is",
|
||||
"ROLE_TABLE_CELL"
|
||||
],
|
||||
[
|
||||
"property",
|
||||
"interfaces",
|
||||
"contains",
|
||||
"TableCell"
|
||||
]
|
||||
]
|
||||
},
|
||||
"title" : "step 1",
|
||||
|
|
|
@ -43,8 +43,14 @@
|
|||
|
||||
function onTimeupdate(event) {
|
||||
if ( config.video.currentTime > ( config.duration || 1 ) ) {
|
||||
config.video.removeEventListener('timeupdate', onTimeupdate);
|
||||
config.video.pause();
|
||||
|
||||
_mediaKeySession.closed
|
||||
.then(onComplete)
|
||||
.catch(onFailure);
|
||||
_mediaKeySession.close()
|
||||
.catch(onFailure);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,9 +59,8 @@
|
|||
return access.createMediaKeys();
|
||||
}).then(function(mediaKeys) {
|
||||
config.video.setMediaKeys(mediaKeys);
|
||||
config.video.addEventListener('timeupdate', onTimeupdate, true);
|
||||
config.video.addEventListener('timeupdate', onTimeupdate);
|
||||
_mediaKeySession = mediaKeys.createSession( 'persistent-license' );
|
||||
_mediaKeySession.closed.then(onComplete);
|
||||
return _mediaKeySession.load(event.data.sessionId);
|
||||
}).then(function( success ) {
|
||||
if ( !success ) throw new DOMException( 'Could not load session' );
|
||||
|
|
|
@ -20,8 +20,15 @@ function runTest(config,qualifier) {
|
|||
_startedReleaseSequence = false,
|
||||
_events = [ ];
|
||||
|
||||
function recordEventFunc( eventType ) {
|
||||
return function() { _events.push( eventType ); };
|
||||
function recordEventFunc(eventType) {
|
||||
return function() { _events.push(eventType); };
|
||||
}
|
||||
|
||||
function recordEventFuncAndCheckExpirationForNaN(eventType) {
|
||||
return function() {
|
||||
_events.push(eventType);
|
||||
assert_equals(_mediaKeySession.expiration, NaN);
|
||||
};
|
||||
}
|
||||
|
||||
function onFailure(error) {
|
||||
|
@ -47,20 +54,28 @@ function runTest(config,qualifier) {
|
|||
_events.push(event.messageType + '-response');
|
||||
return _mediaKeySession.update(response);
|
||||
}).then(test.step_func(function() {
|
||||
_events.push('update-resolved');
|
||||
_events.push(event.messageType + '-response-resolved');
|
||||
if (event.messageType === 'license-release') {
|
||||
checkEventSequence( _events,
|
||||
['generaterequest',
|
||||
['license-request', 'license-request-response', 'update-resolved'], // potentially repeating
|
||||
'keystatuseschange',
|
||||
'playing',
|
||||
'remove-resolved',
|
||||
'keystatuseschange',
|
||||
'license-release',
|
||||
'license-release-response',
|
||||
'closed-attribute-resolved',
|
||||
'update-resolved' ]);
|
||||
test.done();
|
||||
test.step_timeout(function() {
|
||||
checkEventSequence(_events, [
|
||||
'generaterequest',
|
||||
[ // potentially repeating
|
||||
'license-request',
|
||||
'license-request-response',
|
||||
'license-request-response-resolved'
|
||||
],
|
||||
'keystatuseschange-usablekey',
|
||||
'playing',
|
||||
'remove-resolved',
|
||||
'keystatuseschange-allkeysreleased',
|
||||
'license-release',
|
||||
'license-release-response',
|
||||
'closed-attribute-resolved',
|
||||
'license-release-response-resolved',
|
||||
'keystatuseschange-empty'
|
||||
]);
|
||||
test.done();
|
||||
}, 100);
|
||||
}
|
||||
})).catch(onFailure);
|
||||
}
|
||||
|
@ -69,7 +84,21 @@ function runTest(config,qualifier) {
|
|||
assert_equals(event.target, _mediaKeySession);
|
||||
assert_true(event instanceof window.Event);
|
||||
assert_equals(event.type, 'keystatuseschange');
|
||||
_events.push('keystatuseschange');
|
||||
var hasKeys = false,
|
||||
usableKey = false; // true if any key usable.
|
||||
_mediaKeySession.keyStatuses.forEach(function(value, keyid) {
|
||||
assert_in_array(value, ['usable', 'released']);
|
||||
hasKeys = true;
|
||||
usableKey = usableKey || (value === 'usable');
|
||||
});
|
||||
|
||||
if (!hasKeys) {
|
||||
_events.push('keystatuseschange-empty');
|
||||
} else if (usableKey) {
|
||||
_events.push('keystatuseschange-usablekey');
|
||||
} else {
|
||||
_events.push('keystatuseschange-allkeysreleased');
|
||||
}
|
||||
}
|
||||
|
||||
function onEncrypted(event) {
|
||||
|
@ -90,7 +119,9 @@ function runTest(config,qualifier) {
|
|||
_video.load();
|
||||
|
||||
_startedReleaseSequence = true;
|
||||
_mediaKeySession.remove().then(recordEventFunc('remove-resolved')).catch(onFailure);
|
||||
_mediaKeySession.remove()
|
||||
.then(recordEventFuncAndCheckExpirationForNaN('remove-resolved'))
|
||||
.catch(onFailure);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +143,9 @@ function runTest(config,qualifier) {
|
|||
_mediaKeySession = _mediaKeys.createSession( 'persistent-license' );
|
||||
waitForEventAndRunStep('keystatuseschange', _mediaKeySession, onKeyStatusesChange, test);
|
||||
waitForEventAndRunStep('message', _mediaKeySession, onMessage, test);
|
||||
_mediaKeySession.closed.then( recordEventFunc( 'closed-attribute-resolved' ) );
|
||||
_mediaKeySession.closed
|
||||
.then(recordEventFuncAndCheckExpirationForNaN('closed-attribute-resolved'))
|
||||
.catch(onFailure);
|
||||
return testmediasource(config);
|
||||
}).then(function(source) {
|
||||
_mediaSource = source;
|
||||
|
|
|
@ -49,7 +49,7 @@ function runTest(config,qualifier) {
|
|||
function onPlaying(event) {
|
||||
// Not using waitForEventAndRunStep() to avoid too many
|
||||
// EVENT(onTimeUpdate) logs.
|
||||
_video.addEventListener('timeupdate', onTimeupdate, true);
|
||||
_video.addEventListener('timeupdate', onTimeupdate);
|
||||
}
|
||||
|
||||
function onTimeupdate(event) {
|
||||
|
@ -57,16 +57,20 @@ function runTest(config,qualifier) {
|
|||
_video.removeEventListener('timeupdate', onTimeupdate);
|
||||
_video.pause();
|
||||
_video.removeAttribute('src');
|
||||
_video.load()
|
||||
_video.load();
|
||||
|
||||
_mediaKeySession.closed.then(test.step_func(onClosed));
|
||||
_mediaKeySession.close();
|
||||
_mediaKeySession.closed
|
||||
.then(test.step_func(onClosed))
|
||||
.catch(onFailure);
|
||||
_mediaKeySession.close()
|
||||
.catch(onFailure);
|
||||
}
|
||||
}
|
||||
|
||||
function onClosed() {
|
||||
// Open a new window in which we will attempt to play with the persisted license
|
||||
var win = window.open(config.windowscript);
|
||||
assert_not_equals(win, null, "Popup windows not allowed?");
|
||||
|
||||
// Lisen for an event from the new window containing its test assertions
|
||||
window.addEventListener('message', test.step_func(function(messageEvent) {
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
</head>
|
||||
<body>
|
||||
<script>
|
||||
function checkBodyText(request) {
|
||||
function checkBodyText(test, request) {
|
||||
return request.text().then(function(bodyAsText) {
|
||||
assert_equals(bodyAsText, "", "Resolved value should be empty");
|
||||
assert_false(request.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyBlob(request) {
|
||||
function checkBodyBlob(test, request) {
|
||||
return request.blob().then(function(bodyAsBlob) {
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
var reader = new FileReader();
|
||||
|
@ -37,14 +37,14 @@
|
|||
});
|
||||
}
|
||||
|
||||
function checkBodyArrayBuffer(request) {
|
||||
function checkBodyArrayBuffer(test, request) {
|
||||
return request.arrayBuffer().then(function(bodyAsArrayBuffer) {
|
||||
assert_equals(bodyAsArrayBuffer.byteLength, 0, "Resolved value should be empty");
|
||||
assert_false(request.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyJSON(request) {
|
||||
function checkBodyJSON(test, request) {
|
||||
return request.json().then(
|
||||
function(bodyAsJSON) {
|
||||
assert_unreached("JSON parsing should fail");
|
||||
|
@ -54,27 +54,34 @@
|
|||
});
|
||||
}
|
||||
|
||||
function checkBodyFormData(request) {
|
||||
function checkBodyFormData(test, request) {
|
||||
return request.formData().then(function(bodyAsFormData) {
|
||||
assert_true(bodyAsFormData instanceof FormData, "Should receive a FormData");
|
||||
assert_false(request.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkRequestWithNoBody(bodyType, checkFunction) {
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST"});
|
||||
function checkBodyFormDataError(test, request) {
|
||||
return promise_rejects(test, new TypeError(), request.formData()).then(function() {
|
||||
assert_false(request.bodyUsed);
|
||||
return checkFunction(request);
|
||||
});
|
||||
}
|
||||
|
||||
function checkRequestWithNoBody(bodyType, checkFunction, headers = []) {
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "headers": headers});
|
||||
assert_false(request.bodyUsed);
|
||||
return checkFunction(test, request);
|
||||
}, "Consume request's body as " + bodyType);
|
||||
}
|
||||
|
||||
var formData = new FormData();
|
||||
checkRequestWithNoBody("text", checkBodyText);
|
||||
checkRequestWithNoBody("blob", checkBodyBlob);
|
||||
checkRequestWithNoBody("arrayBuffer", checkBodyArrayBuffer);
|
||||
checkRequestWithNoBody("json", checkBodyJSON);
|
||||
checkRequestWithNoBody("formData", checkBodyFormData);
|
||||
checkRequestWithNoBody("json (error case)", checkBodyJSON);
|
||||
checkRequestWithNoBody("formData with correct multipart type (error case)", checkBodyFormDataError, [["Content-Type", 'multipart/form-data; boundary="boundary"']]);
|
||||
checkRequestWithNoBody("formData with correct urlencoded type", checkBodyFormData, [["Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"]]);
|
||||
checkRequestWithNoBody("formData without correct type (error case)", checkBodyFormDataError);
|
||||
|
||||
function checkRequestWithEmptyBody(bodyType, body, asText) {
|
||||
promise_test(function(test) {
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
</head>
|
||||
<body>
|
||||
<script>
|
||||
function checkBodyText(response) {
|
||||
function checkBodyText(test, response) {
|
||||
return response.text().then(function(bodyAsText) {
|
||||
assert_equals(bodyAsText, "", "Resolved value should be empty");
|
||||
assert_false(response.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyBlob(response) {
|
||||
function checkBodyBlob(test, response) {
|
||||
return response.blob().then(function(bodyAsBlob) {
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
var reader = new FileReader();
|
||||
|
@ -37,14 +37,14 @@
|
|||
});
|
||||
}
|
||||
|
||||
function checkBodyArrayBuffer(response) {
|
||||
function checkBodyArrayBuffer(test, response) {
|
||||
return response.arrayBuffer().then(function(bodyAsArrayBuffer) {
|
||||
assert_equals(bodyAsArrayBuffer.byteLength, 0, "Resolved value should be empty");
|
||||
assert_false(response.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyJSON(response) {
|
||||
function checkBodyJSON(test, response) {
|
||||
return response.json().then(
|
||||
function(bodyAsJSON) {
|
||||
assert_unreached("JSON parsing should fail");
|
||||
|
@ -54,27 +54,34 @@
|
|||
});
|
||||
}
|
||||
|
||||
function checkBodyFormData(response) {
|
||||
function checkBodyFormData(test, response) {
|
||||
return response.formData().then(function(bodyAsFormData) {
|
||||
assert_true(bodyAsFormData instanceof FormData, "Should receive a FormData");
|
||||
assert_false(response.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkResponseWithNoBody(bodyType, checkFunction) {
|
||||
promise_test(function(test) {
|
||||
var response = new Response();
|
||||
function checkBodyFormDataError(test, response) {
|
||||
return promise_rejects(test, new TypeError(), response.formData()).then(function() {
|
||||
assert_false(response.bodyUsed);
|
||||
return checkFunction(response);
|
||||
});
|
||||
}
|
||||
|
||||
function checkResponseWithNoBody(bodyType, checkFunction, headers = []) {
|
||||
promise_test(function(test) {
|
||||
var response = new Response(undefined, { "headers": headers });
|
||||
assert_false(response.bodyUsed);
|
||||
return checkFunction(test, response);
|
||||
}, "Consume response's body as " + bodyType);
|
||||
}
|
||||
|
||||
var formData = new FormData();
|
||||
checkResponseWithNoBody("text", checkBodyText);
|
||||
checkResponseWithNoBody("blob", checkBodyBlob);
|
||||
checkResponseWithNoBody("arrayBuffer", checkBodyArrayBuffer);
|
||||
checkResponseWithNoBody("json", checkBodyJSON);
|
||||
checkResponseWithNoBody("formData", checkBodyFormData);
|
||||
checkResponseWithNoBody("json (error case)", checkBodyJSON);
|
||||
checkResponseWithNoBody("formData with correct multipart type (error case)", checkBodyFormDataError, [["Content-Type", 'multipart/form-data; boundary="boundary"']]);
|
||||
checkResponseWithNoBody("formData with correct urlencoded type", checkBodyFormData, [["Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"]]);
|
||||
checkResponseWithNoBody("formData without correct type (error case)", checkBodyFormDataError);
|
||||
|
||||
function checkResponseWithEmptyBody(bodyType, body, asText) {
|
||||
promise_test(function(test) {
|
||||
|
|
|
@ -21,7 +21,7 @@ async_test(t => {
|
|||
const callback = t.step_func(event => {
|
||||
events.push(event.type);
|
||||
if (event.type == 'fullscreenchange') {
|
||||
setTimeout(t.unreached_func('timer callback'));
|
||||
step_timeout(t.unreached_func('timer callback'));
|
||||
requestAnimationFrame(t.step_func_done(() => {
|
||||
assert_array_equals(events, ['resize', 'fullscreenchange'], 'event order');
|
||||
}));
|
||||
|
|
|
@ -12,18 +12,26 @@ async_test(t => {
|
|||
// We are now in fullscreen.
|
||||
assert_equals(document.fullscreenElement, div);
|
||||
|
||||
document.onfullscreenchange = t.step_func(() => {
|
||||
assert_equals(document.fullscreenElement, null);
|
||||
// Done, but ensure that there's only one fullscreenchange event.
|
||||
document.onfullscreenchange = t.unreached_func("second fullscreenchange event");
|
||||
setTimeout(t.step_func_done(), 0);
|
||||
});
|
||||
|
||||
// Exit fullscreen twice.
|
||||
document.exitFullscreen();
|
||||
assert_equals(document.fullscreenElement, div, "fullscreenElement after first exitFullscreen()");
|
||||
document.exitFullscreen();
|
||||
const secondPromise = document.exitFullscreen();
|
||||
assert_equals(document.fullscreenElement, div, "fullscreenElement after second exitFullscreen()");
|
||||
|
||||
document.onfullscreenchange = t.step_func(() => {
|
||||
assert_equals(document.fullscreenElement, null);
|
||||
// Ensure that there's only one fullscreenchange event.
|
||||
document.onfullscreenchange = t.unreached_func("second fullscreenchange event");
|
||||
t.step_timeout(() => {
|
||||
// Done, but if a promise was returned, assert that it is resolved and
|
||||
// not rejected. This test does not fail if promises aren't implemented.
|
||||
if (secondPromise) {
|
||||
secondPromise.then(t.step_func_done(), t.unreached_func("second promise rejected"));
|
||||
} else {
|
||||
t.done();
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
document.onfullscreenerror = t.unreached_func("fullscreenerror event");
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Element#requestFullscreen() when the document is not the active document</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<iframe allowfullscreen></iframe>
|
||||
<script>
|
||||
var t = async_test();
|
||||
|
||||
onload = t.step_func(() => {
|
||||
var iframe = document.querySelector("iframe");
|
||||
var documentBeforeNav = iframe.contentDocument;
|
||||
documentBeforeNav.onfullscreenchange = t.unreached_func('fullscreenchange event');
|
||||
documentBeforeNav.onfullscreenerror = t.unreached_func('fullscreenerror event');
|
||||
|
||||
iframe.onload = t.step_func(() => {
|
||||
var p = documentBeforeNav.documentElement.requestFullscreen();
|
||||
// If a promise was returned, it should already be rejected, so its reject
|
||||
// callback should be invoked before a second promise's callback.
|
||||
// This test does not fail if promises aren't implemented.
|
||||
if (p) {
|
||||
var rejected = false;
|
||||
p.catch(t.step_func(() => rejected = true));
|
||||
Promise.resolve().then(t.step_func(() => assert_true(rejected)));
|
||||
}
|
||||
// Per spec the fullscreenerror event should be fired at the next animtion
|
||||
// frame, but at least Gecko and WebKit will instead effectively do "queue a
|
||||
// task to fire ...". Use both rAF and setTimeout to fail even if the timing
|
||||
// of the (unexpected) event isn't as expected.
|
||||
requestAnimationFrame(t.step_func(() => {
|
||||
step_timeout(t.step_func_done());
|
||||
}));
|
||||
});
|
||||
|
||||
// Navigate the iframe
|
||||
window[0].location.href = '/common/blank.html';
|
||||
});
|
||||
</script>
|
|
@ -27,7 +27,7 @@ async_test(t => {
|
|||
iframeDoc.exitFullscreen();
|
||||
} else if (count == 4) {
|
||||
// Done, but set timeout to fail on extra events.
|
||||
setTimeout(t.step_func_done());
|
||||
step_timeout(t.step_func_done());
|
||||
}
|
||||
});
|
||||
document.onfullscreenerror = t.unreached_func('fullscreenerror event');
|
||||
|
|
|
@ -19,7 +19,7 @@ async_test(t => {
|
|||
iframeDocument.body.requestFullscreen();
|
||||
iframe.remove();
|
||||
// No events will be fired, end test after 100ms.
|
||||
setTimeout(t.step_func_done(() => {
|
||||
step_timeout(t.step_func_done(() => {
|
||||
assert_equals(document.fullscreenElement, null);
|
||||
assert_equals(iframeDocument.fullscreenElement, null);
|
||||
}), 100);
|
||||
|
|
|
@ -15,7 +15,7 @@ async_test(t => {
|
|||
const callback = t.step_func(event => {
|
||||
events.push(event.type);
|
||||
if (event.type == 'fullscreenchange') {
|
||||
setTimeout(t.unreached_func('timer callback'));
|
||||
step_timeout(t.unreached_func('timer callback'));
|
||||
requestAnimationFrame(t.step_func_done(() => {
|
||||
assert_array_equals(events, ['resize', 'fullscreenchange'], 'event order');
|
||||
}));
|
||||
|
@ -30,7 +30,7 @@ async_test(t => {
|
|||
// If fullscreenerror is an animation frame event, then animation frame
|
||||
// callbacks should be run after it is fired, before the timer callback.
|
||||
document.onfullscreenerror = t.step_func(() => {
|
||||
setTimeout(t.unreached_func('timer callback'));
|
||||
step_timeout(t.unreached_func('timer callback'));
|
||||
requestAnimationFrame(t.step_func_done());
|
||||
});
|
||||
}, 'Timing of fullscreenerror event');
|
||||
|
|
|
@ -12,7 +12,7 @@ async_test(t => {
|
|||
assert_equals(document.fullscreenElement, div);
|
||||
// Done, but ensure that there's only one fullscreenchange event.
|
||||
document.onfullscreenchange = t.unreached_func("second fullscreenchange event");
|
||||
setTimeout(t.step_func_done(), 0);
|
||||
step_timeout(t.step_func_done());
|
||||
});
|
||||
document.onfullscreenerror = t.unreached_func("fullscreenerror event");
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Fullscreen IDL tests</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/WebIDLParser.js></script>
|
||||
<script src=/resources/idlharness.js></script>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
function doTest([dom, fullscreen]) {
|
||||
var idlArray = new IdlArray();
|
||||
idlArray.add_untested_idls(dom);
|
||||
idlArray.add_untested_idls('interface EventHandler {};');
|
||||
idlArray.add_idls(fullscreen);
|
||||
idlArray.add_objects({
|
||||
Document: ['new Document'],
|
||||
Element: ['document.createElementNS(null, "test")'],
|
||||
});
|
||||
idlArray.test();
|
||||
}
|
||||
|
||||
function fetchText(url) {
|
||||
return fetch(url).then((response) => response.text());
|
||||
}
|
||||
|
||||
promise_test(() => {
|
||||
return Promise.all(["/interfaces/dom.idl",
|
||||
"/interfaces/fullscreen.idl"].map(fetchText))
|
||||
.then(doTest);
|
||||
}, "Test driver");
|
||||
</script>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче