Merge pull request #15029 from TalbotG/Values3-GT-PR4
Added 7 new css-values tests and 2 reference files
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 387c55a..acfb099 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -6,9 +6,13 @@
# https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables
# https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/index
#
-# In addition to this configuration file, the "Build pull requests from forks
-# of this repository" setting must also be enabled in the Azure DevOps project:
-# https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github#validate-contributions-from-forks
+# In addition to this configuration file, some setup in the Azure DevOps
+# project is required:
+# - The "Build pull requests from forks of this repository" setting must be
+# enabled: https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github#validate-contributions-from-forks
+# - A scheduled build needs to be set up for the the epochs/daily branch.
+# - To get results from scheduled builds into wpt.fyi, a service connection
+# named wpt.fyi with URL https://wpt.fyi is needed.
jobs:
# The affected tests jobs are unconditional for speed, as most PRs have one or
@@ -125,7 +129,7 @@
- job: all_macOS
displayName: 'all tests (Safari Technology Preview)'
- condition: eq(variables['Build.SourceBranch'], 'refs/heads/epochs/daily')
+ condition: eq(variables['Build.Reason'], 'Schedule')
strategy:
parallel: 4 # chosen to make runtime ~2h
timeoutInMinutes: 360
@@ -148,3 +152,20 @@
inputs:
artifactName: 'results'
condition: succeededOrFailed()
+
+# The InvokeRESTAPI task can only run in a server job.
+- job: all_post
+ displayName: 'all tests (wpt.fyi hook)'
+ dependsOn: all_macOS
+ pool: server
+ steps:
+ - task: InvokeRESTAPI@1
+ displayName: 'Invoke wpt.fyi hook'
+ inputs:
+ serviceConnection: wpt.fyi
+ urlSuffix: /api/checks/azure/$(Build.BuildId)
+ - task: InvokeRESTAPI@1
+ displayName: 'Invoke staging.wpt.fyi hook'
+ inputs:
+ serviceConnection: staging.wpt.fyi
+ urlSuffix: /api/checks/azure/$(Build.BuildId)
diff --git a/.taskcluster.yml b/.taskcluster.yml
index 4a6de3b..ae99c09 100644
--- a/.taskcluster.yml
+++ b/.taskcluster.yml
@@ -61,7 +61,7 @@
owner: ${event.pusher.email}
source: ${event.repository.url}
payload:
- image: harjgam/web-platform-tests:0.25
+ image: harjgam/web-platform-tests:0.26
maxRunTime: 7200
artifacts:
public/results:
@@ -136,7 +136,7 @@
owner: ${event.pull_request.user.login}@users.noreply.github.com
source: ${event.repository.url}
payload:
- image: harjgam/web-platform-tests:0.25
+ image: harjgam/web-platform-tests:0.26
maxRunTime: 7200
artifacts:
public/results:
diff --git a/IndexedDB/idb-explicit-commit.any.js b/IndexedDB/idb-explicit-commit.any.js
index da4bd8c..12e56cc 100644
--- a/IndexedDB/idb-explicit-commit.any.js
+++ b/IndexedDB/idb-explicit-commit.any.js
@@ -188,20 +188,17 @@
});
// Txn1 should commit before txn2, even though txn2 uses commit().
const txn1 = db.transaction(['books'], 'readwrite');
- const objectStore1 = txn1.objectStore('books');
- const putRequest1 = objectStore1.put({isbn:'one', title:'title1'});
+ txn1.objectStore('books').put({isbn: 'one', title: 'title1'});
const releaseTxnFunction = keepAlive(testCase, txn1, 'books');
const txn2 = db.transaction(['books'], 'readwrite');
- const objectStore2 = txn2.objectStore('books');
- const putRequest2 = objectStore2.put({isbn:'one', title:'title2'});
+ txn2.objectStore('books').put({isbn:'one', title:'title2'});
txn2.commit();
// Exercise the IndexedDB transaction ordering by executing one with a
// different scope.
const txn3 = db.transaction(['not_books'], 'readwrite');
- const objectStore3 = txn3.objectStore('not_books');
- objectStore3.put({'title': 'not_title'}, 'key');
+ txn3.objectStore('not_books').put({'title': 'not_title'}, 'key');
txn3.oncomplete = function() {
releaseTxnFunction();
}
@@ -210,8 +207,7 @@
// Read the data back to verify that txn2 executed last.
const txn4 = db.transaction(['books'], 'readonly');
- const objectStore4 = txn4.objectStore('books');
- const getRequest4 = objectStore4.get('one');
+ const getRequest4 = txn4.objectStore('books').get('one');
await promiseForTransaction(testCase, txn4);
assert_equals(getRequest4.result.title, 'title2');
db.close();
@@ -225,8 +221,7 @@
});
// Txn1 creates the book 'one' so the 'add()' below fails.
const txn1 = db.transaction(['books'], 'readwrite');
- const objectStore1 = txn1.objectStore('books');
- const putRequest1 = objectStore1.add({isbn:'one', title:'title1'});
+ txn1.objectStore('books').add({isbn:'one', title:'title1'});
txn1.commit();
await promiseForTransaction(testCase, txn1);
@@ -235,15 +230,17 @@
const txn2 = db.transaction(['books'], 'readwrite');
const objectStore2 = txn2.objectStore('books');
objectStore2.put({isbn:'two', title:'title2'});
- const addRequest2 = objectStore2.add({isbn:'one', title:'title2'});
+ const addRequest = objectStore2.add({isbn:'one', title:'title2'});
txn2.commit();
- txn2.oncomplete = assert_unreached(
- 'Transaction with invalid "add" call should not be completed.');
+ txn2.oncomplete = () => { assert_unreached(
+ 'Transaction with invalid "add" call should not be completed.'); };
- var addWatcher = requestWatcher(testCase, addRequest2);
- var txnWatcher = transactionWatcher(testCase, txn2);
- await Promise.all([addWatcher.wait_for('error'),
- txnWatcher.wait_for('error', 'abort')]);
+ // Wait for the transaction to complete. We have to explicitly wait for the
+ // error signal on the transaction because of the nature of the test tooling.
+ await Promise.all([
+ requestWatcher(testCase, addRequest).wait_for('error'),
+ transactionWatcher(testCase, txn2).wait_for(['error', 'abort'])
+ ]);
// Read the data back to verify that txn2 was aborted.
const txn3 = db.transaction(['books'], 'readonly');
@@ -255,3 +252,41 @@
assert_equals(getRequest2.result, 0);
db.close();
}, 'Transactions that explicitly commit and have errors should abort.');
+
+
+promise_test(async testCase => {
+ const db = await createDatabase(testCase, db => {
+ createBooksStore(testCase, db);
+ });
+ const txn1 = db.transaction(['books'], 'readwrite');
+ txn1.objectStore('books').add({isbn: 'one', title: 'title1'});
+ txn1.commit();
+ await promiseForTransaction(testCase, txn1);
+
+ // The second add request will throw an error, but the onerror handler will
+ // appropriately catch the error allowing the valid put request on the
+ // transaction to commit.
+ const txn2 = db.transaction(['books'], 'readwrite');
+ const objectStore2 = txn2.objectStore('books');
+ objectStore2.put({isbn: 'two', title:'title2'});
+ const addRequest = objectStore2.add({isbn: 'one', title:'unreached_title'});
+ addRequest.onerror = (event) => {
+ event.preventDefault();
+ addRequest.transaction.commit();
+ };
+
+ // Wait for the transaction to complete. We have to explicitly wait for the
+ // error signal on the transaction because of the nature of the test tooling.
+ await transactionWatcher(testCase,txn2).wait_for(['error', 'complete'])
+
+ // Read the data back to verify that txn2 was committed.
+ const txn3 = db.transaction(['books'], 'readonly');
+ const objectStore3 = txn3.objectStore('books');
+ const getRequest1 = objectStore3.get('one');
+ const getRequest2 = objectStore3.get('two');
+ await promiseForTransaction(testCase, txn3);
+ assert_equals(getRequest1.result.title, 'title1');
+ assert_equals(getRequest2.result.title, 'title2');
+ db.close();
+}, 'Transactions that handle all errors properly should be behave as ' +
+ 'expected when an explicit commit is called in an onerror handler.');
diff --git a/accelerometer/Accelerometer-supported-by-feature-policy.html b/accelerometer/Accelerometer-supported-by-feature-policy.html
new file mode 100644
index 0000000..8e09c7a
--- /dev/null
+++ b/accelerometer/Accelerometer-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that accelerometer is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://w3c.github.io/sensors/#feature-policy-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('accelerometer', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise accelerometer.');
+</script>
diff --git a/ambient-light/AmbientLightSensor-supported-by-feature-policy.html b/ambient-light/AmbientLightSensor-supported-by-feature-policy.html
new file mode 100644
index 0000000..d5c27c8
--- /dev/null
+++ b/ambient-light/AmbientLightSensor-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that ambient-light-sensor is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://w3c.github.io/sensors/#feature-policy-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('ambient-light-sensor', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise ambient-light-sensor.');
+</script>
diff --git a/animation-worklet/common.js b/animation-worklet/common.js
index eb114f2..15dff82 100644
--- a/animation-worklet/common.js
+++ b/animation-worklet/common.js
@@ -30,3 +30,9 @@
// AnimationWorklet.
return waitForAnimationFrames(count + 1);
}
+
+async function waitForAnimationFrameWithCondition(condition) {
+ do {
+ await new Promise(window.requestAnimationFrame);
+ } while (!condition())
+};
diff --git a/animation-worklet/references/translated-box-ref.html b/animation-worklet/references/translated-box-ref.html
new file mode 100644
index 0000000..c73f5a1
--- /dev/null
+++ b/animation-worklet/references/translated-box-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+#box {
+ width: 100px;
+ height: 100px;
+ transform: translateY(100px);
+ background-color: green;
+}
+</style>
+
+<div id="box"></div>
diff --git a/animation-worklet/worklet-animation-pause-immediately.https.html b/animation-worklet/worklet-animation-pause-immediately.https.html
new file mode 100644
index 0000000..f9dcf30
--- /dev/null
+++ b/animation-worklet/worklet-animation-pause-immediately.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>Verify that calling pause immediately after playing works as expected</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<link rel="match" href="references/translated-box-ref.html">
+
+<script src="/common/reftest-wait.js"></script>
+<script src="/web-animations/testcommon.js"></script>
+<script src="common.js"></script>
+<style>
+#box {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+</style>
+
+<div id="box"></div>
+
+<script>
+registerPassthroughAnimator().then(async _ => {
+ const box = document.getElementById('box');
+ const effect = new KeyframeEffect(box,
+ { transform: ['translateY(100px)', 'translateY(200px)'] },
+ { duration: 100, iterations: 1 }
+ );
+
+ const animation = new WorkletAnimation('passthrough', effect);
+ animation.play();
+ // Immediately pausing animation should freeze the current time at 0.
+ animation.pause();
+ // Wait at least one frame to ensure a paused animation actually freezes.
+ await waitForAsyncAnimationFrames(1);
+ takeScreenshot();
+});
+</script>
+</html>
diff --git a/animation-worklet/worklet-animation-pause-resume.https.html b/animation-worklet/worklet-animation-pause-resume.https.html
new file mode 100644
index 0000000..f26a934
--- /dev/null
+++ b/animation-worklet/worklet-animation-pause-resume.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>Verify that calling pause immediately after playing works as expected</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<link rel="match" href="references/translated-box-ref.html">
+
+<script src="/common/reftest-wait.js"></script>
+<script src="common.js"></script>
+<style>
+#box {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+}
+</style>
+
+<div id="box"></div>
+
+<script>
+registerPassthroughAnimator().then(async _ => {
+ const duration = 18; // a bit longer than a frame
+ const box = document.getElementById('box');
+ const effect = new KeyframeEffect(box,
+ { transform: ['translateY(0px)', 'translateY(100px)'] },
+ { duration: duration, iterations: 1, fill: 'forwards'}
+ );
+
+ const animation = new WorkletAnimation('passthrough', effect);
+ // Immediately pausing animation should freeze the current time at 0.
+ animation.pause();
+ // Playing should cause animation to resume.
+ animation.play();
+ // Wait until we ensure animation has reached completion.
+ await waitForAnimationFrameWithCondition( _ => {
+ return animation.currentTime >= duration;
+ });
+ takeScreenshot();
+});
+</script>
+</html>
diff --git a/animation-worklet/worklet-animation-pause.https.html b/animation-worklet/worklet-animation-pause.https.html
new file mode 100644
index 0000000..4b7a9a0
--- /dev/null
+++ b/animation-worklet/worklet-animation-pause.https.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<title>Verify that currentTime and playState are correct when animation is paused</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/web-animations/testcommon.js"></script>
+<script src="common.js"></script>
+
+<div id="box"></div>
+
+<script>
+
+setup(setupAndRegisterTests, {explicit_done: true});
+
+function createAnimation() {
+ const box = document.getElementById('box');
+ const effect = new KeyframeEffect(box,
+ { transform: ['translateY(100px)', 'translateY(200px)'] },
+ { duration: 100, iterations: 1 }
+ );
+
+ return new WorkletAnimation('passthrough', effect);
+}
+
+async function setupAndRegisterTests() {
+ await registerPassthroughAnimator();
+
+ promise_test(async t => {
+ const animation = createAnimation();
+ animation.play();
+ // Immediately pausing animation should freeze the current time at 0.
+ animation.pause();
+ assert_equals(animation.currentTime, 0);
+ assert_equals(animation.playState, "paused");
+ // Wait some time to ensure a paused animation actually freezes.
+ await waitForNextFrame();
+ assert_equals(animation.currentTime, 0);
+ assert_equals(animation.playState, "paused");
+ }, 'pausing an animation freezes its current time');
+
+ promise_test(async t => {
+ const animation = createAnimation();
+ const startTime = document.timeline.currentTime;
+ animation.pause();
+ animation.play();
+ await waitForNextFrame();
+ const timelineTime = document.timeline.currentTime;
+ assert_equals(animation.playState, "running");
+ assert_greater_than(animation.currentTime, 0);
+ assert_times_equal(animation.currentTime, (timelineTime - startTime));
+ }, 'playing a paused animation should resume it');
+
+ done();
+}
+
+</script>
+
diff --git a/background-fetch/fetch-uploads.https.window.js b/background-fetch/fetch-uploads.https.window.js
index 4ee618a..f93f88a 100644
--- a/background-fetch/fetch-uploads.https.window.js
+++ b/background-fetch/fetch-uploads.https.window.js
@@ -44,3 +44,21 @@
assert_equals(uploaded, uploadData.length);
}, 'Progress event includes uploaded bytes');
+
+backgroundFetchTest(async (test, backgroundFetch) => {
+ const uploadRequest1 =
+ new Request('resources/upload.py', {method: 'POST', body: 'upload1'});
+ const uploadRequest2 =
+ new Request('resources/upload.py', {method: 'POST', body: 'upload2'});
+
+ await backgroundFetch.fetch(uniqueId(), [uploadRequest1, uploadRequest2]);
+
+ const {type, eventRegistration, results} = await getMessageFromServiceWorker();
+ assert_equals(type, 'backgroundfetchsuccess');
+ assert_equals(results.length, 2);
+ assert_equals(eventRegistration.result, 'success');
+ assert_equals(eventRegistration.failureReason, '');
+
+ assert_array_equals([results[0].text, results[1].text].sort(),
+ ['upload1', 'upload2']);
+}, 'Duplicate upload requests work and can be distinguished.');
diff --git a/css/css-shadow-parts/interaction-with-pseudo-elements.html b/css/css-shadow-parts/interaction-with-pseudo-elements.html
new file mode 100644
index 0000000..776ab2e
--- /dev/null
+++ b/css/css-shadow-parts/interaction-with-pseudo-elements.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>CSS Shadow Parts - Interaction with pseudo-elements</title>
+ <meta href="mailto:fergal@chromium.org" rel="author" title="Fergal Daly">
+ <link href="http://www.google.com/" rel="author" title="Google">
+ <link href="https://drafts.csswg.org/css-shadow-parts/" rel="help">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="support/shadow-helper.js"></script>
+ </head>
+ <body>
+ <style>
+ #c-e::part(before-p)::before { color: green; }
+ #c-e::part(after-p)::after { color: green; }
+ #c-e::part(placeholder-p)::placeholder { color: green; }
+ #c-e::part(selection-p)::selection { color: green; }
+ #c-e::part(first-line-p)::first-line { color: green; }
+ #c-e::part(first-letter-p)::first-letter { color: green; }
+ </style>
+ <script>installCustomElement("custom-element", "custom-element-template");</script>
+ <template id="custom-element-template">
+ <style>
+ #before-i::before { content: "this text"; color: red; }
+ #after-i::after { content: "this text"; color: red; }
+ #placeholder-i::placeholder { color: red; }
+ #selection-i::selection { color: red; }
+ #first-line-i::first-line { color: red; }
+ #first-letter-i::first-letter { color: red; }
+ </style>
+ <div>
+ The following text should be green:
+ <span id="before-i" part="before-p"></span>
+ </div>
+ <div>
+ The following text should be green:
+ <span id="after-i" part="after-p"></span>
+ </div>
+ <div>
+ The following text should be green:
+ <input id="placeholder-i" part="placeholder-p" placeholder="this text"></input>
+ </div>
+ <div>
+ The selected text should be green:
+ <div id="selection-i" part="selection-p">select some text</div>
+ </div>
+ <div>
+ The following text should be green:
+ <div id="first-line-i" part="first-line-p">this text<br>Not this</div>
+ </div>
+ <div>
+ The first letter should be green:
+ <div id="first-letter-i" part="first-letter-p"><p>this text</p></div>
+ </div>
+ </template>
+ <custom-element id="c-e"></custom-element>
+ <script>
+ "use strict";
+ const colorGreen = "rgb(0, 128, 0)";
+ test(function() {
+ const el = getElementByShadowIds(document, ["c-e", "before-i"]);
+ assert_equals(window.getComputedStyle(el, '::before').color, colorGreen);
+ }, "::before in selected host is styled");
+ test(function() {
+ const el = getElementByShadowIds(document, ["c-e", "after-i"]);
+ assert_equals(window.getComputedStyle(el, '::after').color, colorGreen);
+ }, "::after in selected host is styled");
+ test(function() {
+ const el = getElementByShadowIds(document, ["c-e", "placeholder-i"]);
+ assert_equals(window.getComputedStyle(el, '::placeholder').color, colorGreen);
+ }, "::placeholder in selected host is styled");
+ test(function() {
+ const el = getElementByShadowIds(document, ["c-e", "selection-i"]);
+ assert_equals(window.getComputedStyle(el, '::selection').color, colorGreen);
+ }, "::selection in selected host is styled");
+ test(function() {
+ const el = getElementByShadowIds(document, ["c-e", "first-line-i"]);
+ assert_equals(window.getComputedStyle(el, '::first-line').color, colorGreen);
+ }, "::first-line in selected host is styled");
+ test(function() {
+ const el = getElementByShadowIds(document, ["c-e", "first-letter-i"]);
+ assert_equals(window.getComputedStyle(el, '::first-letter').color, colorGreen);
+ }, "::first-letter in selected host is styled");
+ </script>
+ </body>
+</html>
diff --git a/css/css-shadow-parts/interaction-with-tree-abiding.html b/css/css-shadow-parts/interaction-with-tree-abiding.html
deleted file mode 100644
index c11da7d..0000000
--- a/css/css-shadow-parts/interaction-with-tree-abiding.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>CSS Shadow Parts - Interaction with tree-abiding</title>
- <meta href="mailto:fergal@chromium.org" rel="author" title="Fergal Daly">
- <link href="http://www.google.com/" rel="author" title="Google">
- <link href="https://drafts.csswg.org/css-shadow-parts/" rel="help">
- <script src="/resources/testharness.js"></script>
- <script src="/resources/testharnessreport.js"></script>
- <script src="support/shadow-helper.js"></script>
- </head>
- <body>
- <style>
- #c-e::part(before-p)::before { color: green; }
- #c-e::part(after-p)::after { color: green; }
- #c-e::part(placeholder-p)::placeholder { color: green; }
- </style>
- <script>installCustomElement("custom-element", "custom-element-template");</script>
- <template id="custom-element-template">
- <style>
- #before-i::before { content: "this text"; color: red; }
- #after-i::after { content: "this text"; color: red; }
- #placeholder-i::placeholder { color: red; }
- </style>
- <div>
- The following text should be green:
- <span id="before-i" part="before-p"></span>
- </div>
- <div>
- The following text should be green:
- <span id="after-i" part="after-p"></span>
- </div>
- <div>
- The following text should be green:
- <input id="placeholder-i" part="placeholder-p" placeholder="this text"></input>
- </div>
- </template>
- <custom-element id="c-e"></custom-element>
- <script>
- "use strict";
- const colorGreen = "rgb(0, 128, 0)";
- test(function() {
- const el = getElementByShadowIds(document, ["c-e", "before-i"]);
- assert_equals(window.getComputedStyle(el, '::before').color, colorGreen);
- }, "::before in selected host is styled");
- test(function() {
- const el = getElementByShadowIds(document, ["c-e", "after-i"]);
- assert_equals(window.getComputedStyle(el, '::after').color, colorGreen);
- }, "::after in selected host is styled");
- test(function() {
- const el = getElementByShadowIds(document, ["c-e", "placeholder-i"]);
- assert_equals(window.getComputedStyle(el, '::placeholder').color, colorGreen);
- }, "::placeholder in selected host is styled");
- </script>
- </body>
-</html>
diff --git a/css/css-text/overflow-wrap/overflow-wrap-break-word-002.html b/css/css-text/overflow-wrap/overflow-wrap-break-word-002.html
index 660b7f1..6f90f0c 100644
--- a/css/css-text/overflow-wrap/overflow-wrap-break-word-002.html
+++ b/css/css-text/overflow-wrap/overflow-wrap-break-word-002.html
@@ -22,7 +22,7 @@
</style>
<p>This test passes if there is nothing below this sentence.
-<div> FAIL <div>
+<div> FAIL </div>
<!--
white-space:break-spaces should cause the spaces at the end of the line to be preserved.
Since there is an allowed break point between the first space and the F,
diff --git a/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html b/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html
index 6203b55..05e570b 100644
--- a/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html
+++ b/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html
@@ -22,4 +22,4 @@
</style>
<p>This test passes if the word FAIL does not appear below.
-<div>PASS FAIL<div>
+<div>PASS FAIL</div>
diff --git a/css/css-text/overflow-wrap/overflow-wrap-break-word-004.html b/css/css-text/overflow-wrap/overflow-wrap-break-word-004.html
index b277319..5f36410 100644
--- a/css/css-text/overflow-wrap/overflow-wrap-break-word-004.html
+++ b/css/css-text/overflow-wrap/overflow-wrap-break-word-004.html
@@ -3,6 +3,7 @@
<title>CSS Text Test: overflow-wrap: break-word</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-overflow-wrap-break-word">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<meta name="flags" content="ahem">
<link rel="match" href="reference/overflow-wrap-break-word-001-ref.html">
<meta name="assert" content="A Single leading white-space constitutes a soft breaking opportunity, honoring the 'white-space: pre-wrap' property, that must prevent the word to be broken.">
diff --git a/css/css-text/overflow-wrap/overflow-wrap-break-word-006.html b/css/css-text/overflow-wrap/overflow-wrap-break-word-006.html
new file mode 100644
index 0000000..6dc1b4d
--- /dev/null
+++ b/css/css-text/overflow-wrap/overflow-wrap-break-word-006.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: overflow-wrap: break-word</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-overflow-wrap-break-word">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<meta name="flags" content="ahem">
+<link rel="match" href="reference/overflow-wrap-break-word-001-ref.html">
+<meta name="assert" content="A Single leading white-space constitutes a soft breaking opportunity, honoring the 'white-space: break-spaces' property, that must prevent the word to be broken.">
+<style>
+div {
+ position: relative;
+ font-size: 20px;
+ font-family: Ahem;
+}
+.red {
+ position: absolute;
+ background: green;
+ color: red;
+ width: 100px;
+ height: 100px;
+ z-index: -1;
+}
+.test {
+ color: green;
+ line-height: 1em;
+ width: 5ch;
+ white-space: break-spaces;
+ overflow-wrap: break-word;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="red"><br>XXXXX</div>
+ <div class="test"> XXXXX </div>
+</body>
diff --git a/css/css-text/white-space/break-spaces-004.html b/css/css-text/white-space/break-spaces-004.html
new file mode 100644
index 0000000..e2c043e
--- /dev/null
+++ b/css/css-text/white-space/break-spaces-004.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: white-space: break-spaces</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://drafts.csswg.org/css-text-3/#white-space-property">
+<link rel="help" title="5.2. Breaking Rules for Letters: the word-break property" href="https://drafts.csswg.org/css-text-3/#word-break-property">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-word">
+<meta name="flags" content="ahem">
+<link rel="match" href="reference/pre-wrap-001-ref.html">
+<meta name="assert" content="The word is not broken if there are previous breaking opportunities, honoring the 'white-space: break-spaces' value.">
+<style>
+div {
+ position: relative;
+ font: 20px/1 Ahem;
+}
+.fail {
+ position: absolute;
+ color: red;
+ z-index: -1;
+}
+span { color: green; }
+.test {
+ color: green;
+ width: 2ch;
+
+ white-space: break-spaces;
+ word-break: break-word;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="fail"><span>XX</span><br>XX</div>
+ <div class="test"> XX</div>
+</body>
diff --git a/css/css-text/white-space/break-spaces-005.html b/css/css-text/white-space/break-spaces-005.html
new file mode 100644
index 0000000..d0dafd3
--- /dev/null
+++ b/css/css-text/white-space/break-spaces-005.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: white-space - break-spaces</title>
+<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
+<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://drafts.csswg.org/css-text-3/#white-space-property">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<link rel="match" href="reference/white-space-break-spaces-005-ref.html">
+<meta name="flags" content="ahem">
+<meta name="assert" content="If 'white-space' is set to 'break-spaces', collapsing preserved white-spaces' advance width is not allowed, so that they can be wrapped honoring the 'white-space' propery.">
+<style>
+div {
+ position: relative;
+ font: 10px/1 Ahem;
+}
+.fail {
+ position: absolute;
+ color: red;
+ z-index: -1;
+}
+span { color: green; }
+.test {
+ color: green;
+ width: 100px;
+
+ white-space: break-spaces;
+}
+
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="fail">XXXX<span>XXXXXX</span><br><span>XXXXXXXXXX</span><br><span>XXXXXXXXXX</span><br><span>XXXXXXXXXX</span><br><span>XXXXXXXXXX</span><br><span>XXXXXXXXXX</span><br><span>XXXXXXXXXX</span><br><span>XXXXXXXXXX</span><br><span>XXXXXXXXXX</span><br><span>XX</span>XXXX<span>XXXX</span></div>
+ <div class="test">XXXX XXXX</div>
+</body>
diff --git a/css/css-text/white-space/break-spaces-006.html b/css/css-text/white-space/break-spaces-006.html
new file mode 100644
index 0000000..5f9d605
--- /dev/null
+++ b/css/css-text/white-space/break-spaces-006.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: white-space - break-spaces</title>
+<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
+<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://www.w3.org/TR/css-text-3/#white-space-property">
+<link rel="help" title="5.2. Breaking Rules for Letters: the word-break property" href="https://drafts.csswg.org/css-text-3/#word-break-property">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
+<link rel="match" href="reference/white-space-break-spaces-005-ref.html">
+<meta name="flags" content="ahem">
+<meta name="assert" content="White spaces are preserved, honoring the 'white-space: break-spaces', but the words are broken, honring the 'word-beak: break-all' even though there are previous breaking opportunities in the white-spaces.">
+<style>
+div {
+ position: relative;
+ font: 25px/1 Ahem;
+}
+.fail {
+ position: absolute;
+ color: red;
+ z-index: -1;
+}
+span { color: green; }
+.test {
+ color: green;
+ width: 4ch;
+
+ white-space: break-spaces;
+ word-break: break-all;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="fail"><span>X</span>XXX<br>X<span>X</span>XX<br>X<span>XXX</span><br><span>XXXX</span></div>
+ <div class="test"> XXXX XXX</div>
+</body>
diff --git a/css/css-text/white-space/break-spaces-007.html b/css/css-text/white-space/break-spaces-007.html
new file mode 100644
index 0000000..7721361
--- /dev/null
+++ b/css/css-text/white-space/break-spaces-007.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: white-space - break-spaces</title>
+<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
+<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://www.w3.org/TR/css-text-3/#white-space-property">
+<link rel="help" title="5.2. Breaking Rules for Letters: the word-break property" href="https://drafts.csswg.org/css-text-3/#word-break-property">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
+<link rel="match" href="reference/white-space-break-spaces-005-ref.html">
+<meta name="flags" content="ahem">
+<meta name="assert" content="A single leading white-space should be used, honoring white-space: break-spaces, to avoid overflow; however, a single preserved white-space at the end of the line cannot be wrapped, hence it hangs when breaking after it to move the rest of the text to the next line.">
+<style>
+div {
+ position: relative;
+ font: 25px/1 Ahem;
+}
+.fail {
+ position: absolute;
+ color: red;
+ z-index: -1;
+}
+span { color: green; }
+.test {
+ color: green;
+ width: 4ch;
+
+ white-space: break-spaces;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="fail"><span>XXXX</span><br>XXXX<br>XXX<span>X</span><br><span>XXXX</span></div>
+ <div class="test"> XXXX XXX</div>
+</body>
diff --git a/css/css-text/white-space/break-spaces-008.html b/css/css-text/white-space/break-spaces-008.html
new file mode 100644
index 0000000..d183cac
--- /dev/null
+++ b/css/css-text/white-space/break-spaces-008.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: white-space - break-spaces</title>
+<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
+<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://www.w3.org/TR/css-text-3/#white-space-property">
+<link rel="help" title="5.2. Breaking Rules for Letters: the word-break property" href="https://drafts.csswg.org/css-text-3/#word-break-property">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
+<link rel="match" href="reference/white-space-break-spaces-005-ref.html">
+<meta name="flags" content="ahem">
+<meta name="assert" content="White spaces are preserved, honoring the 'white-space: break-spaces', which may lead to overfow. However, we can break before the first white-space after the word honoring the 'break-all' value.">
+<style>
+div {
+ position: relative;
+ font: 25px/1 Ahem;
+}
+.fail {
+ position: absolute;
+ color: red;
+ z-index: -1;
+}
+span { color: green; }
+.test {
+ color: green;
+ width: 4ch;
+
+ white-space: break-spaces;
+ word-break: break-all;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="fail">XXXX<br><span>X</span>XX<span>X</span><br><span>XXXX</span><br><span>XXXX</span></div>
+ <div class="test">XXXX XX</div>
+</body>
diff --git a/css/css-text/white-space/pre-wrap-016.html b/css/css-text/white-space/pre-wrap-016.html
new file mode 100644
index 0000000..5f66a7b
--- /dev/null
+++ b/css/css-text/white-space/pre-wrap-016.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: white-space: pre-wrap</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-word">
+<meta name="flags" content="ahem">
+<link rel="match" href="reference/pre-wrap-001-ref.html">
+<meta name="assert" content="The word is not broken if there are previous breaking opportunities, honoring the white-space: pre-wrap value.">
+<style>
+div {
+ position: relative;
+ font-size: 20px;
+ font-family: Ahem;
+}
+.red {
+ position: absolute;
+ white-space: pre;
+ background: green;
+ color: red;
+ width: 40px;
+ height: 40px;
+ z-index: -1;
+}
+.test {
+ color: green;
+ line-height: 1em;
+ width: 2ch;
+
+ white-space: pre-wrap;
+ word-break: break-word;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="red"><br>XX</div>
+ <div class="test"> XX</div>
+</body>
diff --git a/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html b/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html
new file mode 100644
index 0000000..3247ae5
--- /dev/null
+++ b/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Reference File</title>
+<link rel="author" title="Javier Fernandez" href="mailto:jfernandez@igalia.com" />
+<style>
+div {
+ position: relative;
+ width: 100px;
+ height: 100px;
+ background: green;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/css/css-text/word-break/word-break-break-all-010.html b/css/css-text/word-break/word-break-break-all-010.html
index 7d3bc05..be46d29 100644
--- a/css/css-text/word-break/word-break-break-all-010.html
+++ b/css/css-text/word-break/word-break-break-all-010.html
@@ -1,8 +1,9 @@
<!DOCTYPE html>
<meta charset="utf-8">
-<title>CSS Text Test: overflow-wrap: break-word</title>
+<title>CSS Text Test: word-break: break-all</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<meta name="flags" content="ahem">
<link rel="match" href="reference/word-break-break-all-010-ref.html">
<meta name="assert" content="The word is broken even if pre-wrap provides a former breaking opportunity in leading white-space.">
diff --git a/css/css-text/word-break/word-break-break-all-011.html b/css/css-text/word-break/word-break-break-all-011.html
index 531c68d..fade439 100644
--- a/css/css-text/word-break/word-break-break-all-011.html
+++ b/css/css-text/word-break/word-break-break-all-011.html
@@ -1,8 +1,9 @@
<!DOCTYPE html>
<meta charset="utf-8">
-<title>CSS Text Test: overflow-wrap: break-word</title>
+<title>CSS Text Test: word-break: break-all</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<meta name="flags" content="ahem">
<link rel="match" href="reference/word-break-break-all-010-ref.html">
<meta name="assert" content="A single leading white-space should account as soft breaking opportunity, honoring the 'white-space: pre-wrap', on top to the ones provided by 'word-break: break-all'.">
diff --git a/css/css-text/word-break/word-break-break-all-012.html b/css/css-text/word-break/word-break-break-all-012.html
new file mode 100644
index 0000000..cd3d440
--- /dev/null
+++ b/css/css-text/word-break/word-break-break-all-012.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: overflow-wrap: break-word</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<meta name="flags" content="ahem">
+<link rel="match" href="reference/word-break-break-all-010-ref.html">
+<meta name="assert" content="The word is broken even if white-space: break-spaces provides a former breaking opportunity in leading white-space.">
+<style>
+div {
+ position: relative;
+ font-size: 20px;
+ font-family: Ahem;
+}
+.red {
+ position: absolute;
+ white-space: pre;
+ background: green;
+ color: red;
+ width: 100px;
+ height: 100px;
+ z-index: -1;
+}
+.test {
+ color: green;
+ line-height: 1em;
+ width: 5ch;
+
+ white-space: break-spaces;
+ word-break: break-all;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="red"> XXXX<br>X</div>
+ <div class="test"> XXXXX</div>
+</body>
diff --git a/css/css-text/word-break/word-break-break-all-013.html b/css/css-text/word-break/word-break-break-all-013.html
new file mode 100644
index 0000000..85dce08
--- /dev/null
+++ b/css/css-text/word-break/word-break-break-all-013.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: word-break: break-all</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
+<meta name="flags" content="ahem">
+<link rel="match" href="reference/word-break-break-all-010-ref.html">
+<meta name="assert" content="A single leading white-space should account as soft breaking opportunity, honoring the 'white-space: break-spaces', on top to the ones provided by 'word-break: break-all'.">
+<style>
+div {
+ position: relative;
+ font-size: 20px;
+ font-family: Ahem;
+}
+.red {
+ position: absolute;
+ background: green;
+ color: red;
+ width: 100px;
+ height: 100px;
+ z-index: -1;
+}
+.test {
+ color: green;
+ background: green;
+ line-height: 1em;
+ width: 1ch;
+ white-space: break-spaces;
+ word-break: break-all;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="red">X<br>X<br>X</div>
+ <div class="test"> XX</div>
+</body>
diff --git a/css/css-values/attr-color-invalid-fallback.html b/css/css-values/attr-color-invalid-fallback.html
index 9225889..9e016d1 100644
--- a/css/css-values/attr-color-invalid-fallback.html
+++ b/css/css-values/attr-color-invalid-fallback.html
@@ -9,7 +9,7 @@
<meta name="assert" content="
When the fallback value of an attr() function is invalid, the delcaration is ignored.
" />
-
+ <meta name="flags" content="invalid">
<link
rel="author"
title="François REMY"
diff --git a/css/css-values/attr-invalid-type-001.html b/css/css-values/attr-invalid-type-001.html
index c427ade..1f88c37 100644
--- a/css/css-values/attr-invalid-type-001.html
+++ b/css/css-values/attr-invalid-type-001.html
@@ -9,7 +9,7 @@
<meta name="assert" content="
When the type of an attr() function is known and unexpected, the declaration is ignored
" />
-
+ <meta name="flags" content="invalid">
<link
rel="author"
title="François REMY"
diff --git a/css/css-values/attr-invalid-type-002.html b/css/css-values/attr-invalid-type-002.html
index 797700d..dbdac8a 100644
--- a/css/css-values/attr-invalid-type-002.html
+++ b/css/css-values/attr-invalid-type-002.html
@@ -9,7 +9,7 @@
<meta name="assert" content="
When the type of an attr() function is known and unexpected, the declaration is ignored
" />
-
+ <meta name="flags" content="invalid">
<link
rel="author"
title="François REMY"
diff --git a/css/css-values/attr-length-invalid-fallback.html b/css/css-values/attr-length-invalid-fallback.html
index 6a5d4df..e68fe7a 100644
--- a/css/css-values/attr-length-invalid-fallback.html
+++ b/css/css-values/attr-length-invalid-fallback.html
@@ -9,7 +9,7 @@
<meta name="assert" content="
When the attr() fallback is an invalid length, the delcaration is correctly ignored.
" />
-
+ <meta name="flags" content="invalid">
<link
rel="author"
title="François REMY"
diff --git a/css/css-values/attr-px-invalid-fallback.html b/css/css-values/attr-px-invalid-fallback.html
index 778697d..f8f88f5 100644
--- a/css/css-values/attr-px-invalid-fallback.html
+++ b/css/css-values/attr-px-invalid-fallback.html
@@ -9,7 +9,7 @@
<meta name="assert" content="
When the fallback of a pixel attribute reference is invalid, the declaration is ignored.
" />
-
+ <meta name="flags" content="invalid">
<link
rel="author"
title="François REMY"
diff --git a/encrypted-media/clearkey-check-encryption-scheme.https.html b/encrypted-media/clearkey-check-encryption-scheme.https.html
new file mode 100644
index 0000000..eb580ea
--- /dev/null
+++ b/encrypted-media/clearkey-check-encryption-scheme.https.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Encrypted Media Extensions: Check encryptionScheme with Clear Key</title>
+ <link rel="help" href="https://w3c.github.io/encrypted-media/">
+
+ <!-- Web Platform Test Harness scripts -->
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+
+ <!-- Helper scripts for Encrypted Media Extensions tests -->
+ <script src=/encrypted-media/util/utils.js></script>
+ <script src=/encrypted-media/util/utf8.js></script>
+
+ <!-- Content metadata -->
+ <!--<script src=/encrypted-media/content/content-metadata.js></script>-->
+
+ <!-- The script for this specific test -->
+ <script src=/encrypted-media/scripts/check-encryption-scheme.js></script>
+
+ </head>
+ <body>
+ <div id='log'></div>
+
+ <script>
+ var config = { keysystem: 'org.w3.clearkey' }
+
+ runTest(config);
+ </script>
+ </body>
+</html>
diff --git a/encrypted-media/clearkey-check-status-for-hdcp.https.html b/encrypted-media/clearkey-check-status-for-hdcp.https.html
new file mode 100644
index 0000000..5ec3b26
--- /dev/null
+++ b/encrypted-media/clearkey-check-status-for-hdcp.https.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Encrypted Media Extensions: Check HDCP status with Clear Key</title>
+ <link rel="help" href="https://w3c.github.io/encrypted-media/">
+
+ <!-- Web Platform Test Harness scripts -->
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+
+ <!-- Helper scripts for Encrypted Media Extensions tests -->
+ <script src=/encrypted-media/util/utils.js></script>
+ <script src=/encrypted-media/util/utf8.js></script>
+
+ <!-- Content metadata -->
+ <!--<script src=/encrypted-media/content/content-metadata.js></script>-->
+
+ <!-- The script for this specific test -->
+ <script src=/encrypted-media/scripts/check-status-for-hdcp.js></script>
+
+ </head>
+ <body>
+ <div id='log'></div>
+
+ <script>
+ var config = { keysystem: 'org.w3.clearkey' }
+
+ runTest(config);
+ </script>
+ </body>
+</html>
diff --git a/encrypted-media/drm-check-encryption-scheme.https.html b/encrypted-media/drm-check-encryption-scheme.https.html
new file mode 100644
index 0000000..862591b
--- /dev/null
+++ b/encrypted-media/drm-check-encryption-scheme.https.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Encrypted Media Extensions: Check encryptionScheme with DRM</title>
+ <link rel="help" href="https://w3c.github.io/encrypted-media/">
+
+ <!-- Web Platform Test Harness scripts -->
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+
+ <!-- Helper scripts for Encrypted Media Extensions tests -->
+ <script src=/encrypted-media/util/utils.js></script>
+ <script src=/encrypted-media/util/utf8.js></script>
+
+ <!-- Content metadata -->
+ <!--<script src=/encrypted-media/content/content-metadata.js></script>-->
+
+ <!-- The script for this specific test -->
+ <script src=/encrypted-media/scripts/check-encryption-scheme.js></script>
+
+ </head>
+ <body>
+ <div id='log'></div>
+
+ <script>
+ var config = { keysystem: getSupportedKeySystem() }
+
+ runTest(config);
+ </script>
+ </body>
+</html>
diff --git a/encrypted-media/drm-check-status-for-hdcp.https.html b/encrypted-media/drm-check-status-for-hdcp.https.html
new file mode 100644
index 0000000..68c45be
--- /dev/null
+++ b/encrypted-media/drm-check-status-for-hdcp.https.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Encrypted Media Extensions: Check HDCP status with DRM</title>
+ <link rel="help" href="https://w3c.github.io/encrypted-media/">
+
+ <!-- Web Platform Test Harness scripts -->
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+
+ <!-- Helper scripts for Encrypted Media Extensions tests -->
+ <script src=/encrypted-media/util/utils.js></script>
+ <script src=/encrypted-media/util/utf8.js></script>
+
+ <!-- Content metadata -->
+ <!--<script src=/encrypted-media/content/content-metadata.js></script>-->
+
+ <!-- The script for this specific test -->
+ <script src=/encrypted-media/scripts/check-status-for-hdcp.js></script>
+
+ </head>
+ <body>
+ <div id='log'></div>
+
+ <script>
+ var config = { keysystem: getSupportedKeySystem() }
+
+ runTest(config);
+ </script>
+ </body>
+</html>
diff --git a/encrypted-media/encrypted-media-supported-by-feature-policy.tentative.html b/encrypted-media/encrypted-media-supported-by-feature-policy.tentative.html
new file mode 100644
index 0000000..5b2d224
--- /dev/null
+++ b/encrypted-media/encrypted-media-supported-by-feature-policy.tentative.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that encrypted-media is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://github.com/w3c/encrypted-media/pull/432">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('encrypted-media', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise encrypted-media.');
+</script>
diff --git a/encrypted-media/scripts/check-encryption-scheme.js b/encrypted-media/scripts/check-encryption-scheme.js
new file mode 100644
index 0000000..5d62927
--- /dev/null
+++ b/encrypted-media/scripts/check-encryption-scheme.js
@@ -0,0 +1,41 @@
+function runTest(config, qualifier)
+{
+ function checkEncryptionScheme(encryptionScheme)
+ {
+ var simpleConfig = getSimpleConfiguration();
+ assert_greater_than(simpleConfig[0].audioCapabilities.length, 0);
+ simpleConfig[0].audioCapabilities.forEach(function(capability) {
+ capability.encryptionScheme = encryptionScheme;
+ });
+
+ return navigator.requestMediaKeySystemAccess(config.keysystem, simpleConfig)
+ .then(
+ function(access) {
+ var actualConfiguration = access.getConfiguration();
+ for (let i = 0; i < actualConfiguration.audioCapabilities.length; i++) {
+ const capability = actualConfiguration.audioCapabilities[i];
+
+ // If "encryptionScheme" is not supported, fail.
+ if (!('encryptionScheme' in capability)) {
+ return Promise.reject('Not implemented');
+ }
+
+ // If "encryptionScheme" is supported, it should be returned.
+ assert_equals(capability.encryptionScheme, encryptionScheme);
+ }
+ return Promise.resolve('Supported');
+ },
+ function error() {
+ // CDM does not support "encryptionScheme". Test should still pass.
+ return Promise.resolve('Not supported');
+ });
+ }
+
+ promise_test(
+ () => checkEncryptionScheme('cenc'),
+ testnamePrefix(qualifier, config.keysystem) + ' support for "cenc" encryption scheme.');
+
+ promise_test(
+ () => checkEncryptionScheme('cbcs'),
+ testnamePrefix(qualifier, config.keysystem) + ' support for "cbcs" encryption scheme.');
+}
diff --git a/encrypted-media/scripts/check-status-for-hdcp.js b/encrypted-media/scripts/check-status-for-hdcp.js
new file mode 100644
index 0000000..ac30819
--- /dev/null
+++ b/encrypted-media/scripts/check-status-for-hdcp.js
@@ -0,0 +1,26 @@
+function runTest(config, qualifier)
+{
+ function checkStatusForMinHdcpVersionPolicy(hdcpVersion)
+ {
+ return navigator.requestMediaKeySystemAccess(config.keysystem, getSimpleConfiguration())
+ .then(function(access) {
+ return access.createMediaKeys();
+ })
+ .then(function(mediaKeys) {
+ // As HDCP policy depends on the hardware running this test,
+ // don't bother checking the result returned as it may or
+ // may not be supported. This simply verifies that
+ // getStatusForPolicy() exists and doesn't blow up.
+ return mediaKeys.getStatusForPolicy({minHdcpVersion: hdcpVersion});
+ });
+ }
+
+ promise_test(
+ () => checkStatusForMinHdcpVersionPolicy(''),
+ testnamePrefix(qualifier, config.keysystem) +
+ ' support for empty HDCP version.');
+
+ promise_test(
+ () => checkStatusForMinHdcpVersionPolicy('1.0'),
+ testnamePrefix(qualifier, config.keysystem) + ' support for HDCP 1.0.');
+}
diff --git a/event-timing/supported-types.window.js b/event-timing/supported-types.window.js
new file mode 100644
index 0000000..c81d501
--- /dev/null
+++ b/event-timing/supported-types.window.js
@@ -0,0 +1,11 @@
+test(() => {
+ if (typeof PerformanceObserver.supportedEntryTypes === "undefined")
+ assert_unreached("supportedEntryTypes is not supported.");
+ const types = PerformanceObserver.supportedEntryTypes;
+ assert_true(types.includes("firstInput"),
+ "There should be 'firstInput' in PerformanceObserver.supportedEntryTypes");
+ assert_true(types.includes("event"),
+ "There should be 'event' in PerformanceObserver.supportedEntryTypes");
+ assert_greater_than(types.indexOf("firstInput"), types.indexOf('event'),
+ "The 'firstInput' entry should appear after the 'event' entry");
+}, "supportedEntryTypes contains 'event' and 'firstInput'.");
diff --git a/feature-policy/payment-supported-by-feature-policy.tentative.html b/feature-policy/payment-supported-by-feature-policy.tentative.html
new file mode 100644
index 0000000..07dec70
--- /dev/null
+++ b/feature-policy/payment-supported-by-feature-policy.tentative.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that payment is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://github.com/w3c/payment-request/issues/600">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('payment', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise payment.');
+</script>
diff --git a/feature-policy/picture-in-picture-supported-by-feature-policy.html b/feature-policy/picture-in-picture-supported-by-feature-policy.html
new file mode 100644
index 0000000..a65c682
--- /dev/null
+++ b/feature-policy/picture-in-picture-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that picture-in-picture is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://wicg.github.io/picture-in-picture/#feature-policy">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('picture-in-picture', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise picture-in-picture.');
+</script>
diff --git a/feature-policy/reporting/unoptimized-image.jpg b/feature-policy/reporting/unoptimized-image.jpg
new file mode 100644
index 0000000..599137a
--- /dev/null
+++ b/feature-policy/reporting/unoptimized-image.jpg
Binary files differ
diff --git a/feature-policy/reporting/unoptimized-images-reporting.html b/feature-policy/reporting/unoptimized-images-reporting.html
new file mode 100644
index 0000000..fb27a13
--- /dev/null
+++ b/feature-policy/reporting/unoptimized-images-reporting.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src='/resources/testharness.js'></script>
+ <script src='/resources/testharnessreport.js'></script>
+ </head>
+ <body>
+ <img src="./unoptimized-image.jpg">
+ <script>
+var check_report_format = (reports, observer) => {
+ let report = reports[0];
+ assert_equals(report.type, "feature-policy-violation");
+ assert_equals(report.url, document.location.href);
+ assert_equals(report.body.featureId, "unoptimized-images");
+ assert_equals(report.body.disposition, "enforce");
+};
+
+async_test(t => {
+ new ReportingObserver(t.step_func_done(check_report_format),
+ {types: ['feature-policy-violation'], buffered: true}).observe();
+}, "unoptimized-images Report Format");
+ </script>
+ </body>
+</html>
diff --git a/feature-policy/reporting/unoptimized-images-reporting.html.headers b/feature-policy/reporting/unoptimized-images-reporting.html.headers
new file mode 100644
index 0000000..10b4123
--- /dev/null
+++ b/feature-policy/reporting/unoptimized-images-reporting.html.headers
@@ -0,0 +1 @@
+Feature-Policy: unoptimized-images 'none'
diff --git a/fetch/cross-origin-resource-policy/syntax.any.js b/fetch/cross-origin-resource-policy/syntax.any.js
index cf5b06d..dc87497 100644
--- a/fetch/cross-origin-resource-policy/syntax.any.js
+++ b/fetch/cross-origin-resource-policy/syntax.any.js
@@ -8,7 +8,8 @@
"SAME-ORIGIN",
"Same-Origin",
"same-origin, <>",
- "same-origin, same-origin"
+ "same-origin, same-origin",
+ "https://www.example.com", // See https://github.com/whatwg/fetch/issues/760
].forEach(incorrectHeaderValue => {
// Note: an incorrect value results in a successful load, so this test is only meaningful in
// implementations with support for the header.
diff --git a/geolocation-sensor/GeolocationSensor-supported-by-feature-policy.html b/geolocation-sensor/GeolocationSensor-supported-by-feature-policy.html
new file mode 100644
index 0000000..aa05f33
--- /dev/null
+++ b/geolocation-sensor/GeolocationSensor-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that geolocation is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://w3c.github.io/sensors/#feature-policy-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('geolocation', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise geolocation.');
+</script>
diff --git a/gyroscope/Gyroscope-supported-by-feature-policy.html b/gyroscope/Gyroscope-supported-by-feature-policy.html
new file mode 100644
index 0000000..06a4137
--- /dev/null
+++ b/gyroscope/Gyroscope-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that gyroscope is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://w3c.github.io/sensors/#feature-policy-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('gyroscope', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise gyroscope.');
+</script>
diff --git a/html/browsers/origin/cross-origin-objects/cross-origin-objects.html b/html/browsers/origin/cross-origin-objects/cross-origin-objects.html
index caac56a..888343b 100644
--- a/html/browsers/origin/cross-origin-objects/cross-origin-objects.html
+++ b/html/browsers/origin/cross-origin-objects/cross-origin-objects.html
@@ -106,16 +106,22 @@
C.location[prop]; // Shouldn't throw.
Object.getOwnPropertyDescriptor(C.location, prop); // Shouldn't throw.
assert_true(Object.prototype.hasOwnProperty.call(C.location, prop), "hasOwnProperty for " + prop);
+ assert_throws("SecurityError", function() { C.location[prop] = undefined; }, "Should throw when writing to " + prop + " on Location");
+ }
+ else if (prop == 'href') {
+ Object.getOwnPropertyDescriptor(C.location, prop); // Shouldn't throw.
+ assert_true(Object.prototype.hasOwnProperty.call(C.location, prop), "hasOwnProperty for " + prop);
+ assert_throws("SecurityError", function() { C.location[prop] },
+ "Should throw reading href on Location");
}
else {
- assert_throws("SecurityError", function() { C[prop]; }, "Should throw when accessing " + prop + " on Location");
- assert_throws("SecurityError", function() { Object.getOwnPropertyDescriptor(C, prop); },
+ assert_throws("SecurityError", function() { C.location[prop]; }, "Should throw when accessing " + prop + " on Location");
+ assert_throws("SecurityError", function() { Object.getOwnPropertyDescriptor(C.location, prop); },
"Should throw when accessing property descriptor for " + prop + " on Location");
- assert_throws("SecurityError", function() { Object.prototype.hasOwnProperty.call(C, prop); },
+ assert_throws("SecurityError", function() { Object.prototype.hasOwnProperty.call(C.location, prop); },
"Should throw when invoking hasOwnProperty for " + prop + " on Location");
+ assert_throws("SecurityError", function() { C.location[prop] = undefined; }, "Should throw when writing to " + prop + " on Location");
}
- if (prop != 'href')
- assert_throws("SecurityError", function() { C[prop] = undefined; }, "Should throw when writing to " + prop + " on Location");
}
}, "Only whitelisted properties are accessible cross-origin");
@@ -150,11 +156,22 @@
assert_throws(new TypeError, function() { protoSetter.call(C, new Object()); }, "proto setter |call| on cross-origin Window");
assert_throws(new TypeError, function() { protoSetter.call(C.location, new Object()); }, "proto setter |call| on cross-origin Location");
});
+ // Hack to avoid "duplicate test name" harness issues.
+ setters.forEach(function(protoSetter) {
+ test(function() { protoSetter.call(C, null); },
+ "proto setter |call| on cross-origin Window with null (" + protoSetter + ")");
+ test(function() { protoSetter.call(C.location, null); },
+ "proto setter |call| on cross-origin Location with null (" + protoSetter + ")");
+ });
if (Reflect.setPrototypeOf) {
assert_false(Reflect.setPrototypeOf(C, new Object()),
"Reflect.setPrototypeOf on cross-origin Window");
+ assert_true(Reflect.setPrototypeOf(C, null),
+ "Reflect.setPrototypeOf on cross-origin Window with null");
assert_false(Reflect.setPrototypeOf(C.location, new Object()),
"Reflect.setPrototypeOf on cross-origin Location");
+ assert_true(Reflect.setPrototypeOf(C.location, null),
+ "Reflect.setPrototypeOf on cross-origin Location with null");
}
}, "[[SetPrototypeOf]] should return false");
@@ -230,6 +247,19 @@
assert_equals(typeof D.then, "object");
}, "[[GetOwnProperty]] - Subframe named 'then' should shadow the default 'then' value");
+addTest(function() {
+ assert_equals(typeof D.close, "function");
+ assert_equals(typeof D.open, "object");
+}, "[[GetOwnProperty]] - Subframes should be visible cross-origin only if their names don't match the names of cross-origin-exposed IDL properties");
+
+addTest(function() {
+ assert_equals(typeof Object.getOwnPropertyDescriptor(C, '0').value, "object");
+ assert_equals(typeof Object.getOwnPropertyDescriptor(C, '1').value, "object");
+ assert_throws("SecurityError", function() {
+ Object.getOwnPropertyDescriptor(C, '2');
+ });
+}, "[[GetOwnProperty]] - Should be able to get a property descriptor for an indexed property only if it corresponds to a child window.");
+
/*
* [[Delete]]
*/
diff --git a/html/browsers/origin/cross-origin-objects/frame-with-then.html b/html/browsers/origin/cross-origin-objects/frame-with-then.html
index 96cdf1e..1127995 100644
--- a/html/browsers/origin/cross-origin-objects/frame-with-then.html
+++ b/html/browsers/origin/cross-origin-objects/frame-with-then.html
@@ -6,5 +6,9 @@
<!-- A subframe to test "then" behavior -->
<iframe name="then"></iframe>
<iframe name="b"></iframe>
+ <!-- Two subframes with names corresponding to IDL-defined properties; one
+ a cross-origin-exposed property and one not exposed cross-origin -->
+ <iframe name="close"></iframe>
+ <iframe name="open"></iframe>
</body>
</html>
diff --git a/html/semantics/embedded-content/media-elements/autoplay-supported-by-feature-policy.html b/html/semantics/embedded-content/media-elements/autoplay-supported-by-feature-policy.html
new file mode 100644
index 0000000..af4de6b
--- /dev/null
+++ b/html/semantics/embedded-content/media-elements/autoplay-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that autoplay is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/infrastructure.html#policy-controlled-features">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('autoplay', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise autoplay.');
+</script>
diff --git a/interfaces/IndexedDB.idl b/interfaces/IndexedDB.idl
index 137528c..868338b 100644
--- a/interfaces/IndexedDB.idl
+++ b/interfaces/IndexedDB.idl
@@ -200,6 +200,7 @@
readonly attribute DOMException error;
IDBObjectStore objectStore(DOMString name);
+ void commit();
void abort();
// Event handlers:
diff --git a/interfaces/mediastream-recording.idl b/interfaces/mediastream-recording.idl
index 5bf661e..0be0538 100644
--- a/interfaces/mediastream-recording.idl
+++ b/interfaces/mediastream-recording.idl
@@ -18,7 +18,7 @@
readonly attribute unsigned long videoBitsPerSecond;
readonly attribute unsigned long audioBitsPerSecond;
- void start(optional long timeslice);
+ void start(optional unsigned long timeslice);
void stop();
void pause();
void resume();
diff --git a/magnetometer/Magnetometer-supported-by-feature-policy.html b/magnetometer/Magnetometer-supported-by-feature-policy.html
new file mode 100644
index 0000000..a049363
--- /dev/null
+++ b/magnetometer/Magnetometer-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that magnetometer is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://w3c.github.io/sensors/#feature-policy-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('magnetometer', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise magnetometer.');
+</script>
diff --git a/mediacapture-streams/MediaStream-supported-by-feature-policy.html b/mediacapture-streams/MediaStream-supported-by-feature-policy.html
new file mode 100644
index 0000000..ef29ae6
--- /dev/null
+++ b/mediacapture-streams/MediaStream-supported-by-feature-policy.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Test that accelerometer is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://w3c.github.io/mediacapture-main/#feature-policy-integration">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('camera', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise camera.');
+
+test(() => {
+ assert_in_array('microphone', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise microphone.');
+</script>
diff --git a/mediacapture-streams/MediaStreamTrack-getSettings.https.html b/mediacapture-streams/MediaStreamTrack-getSettings.https.html
index 158c901..c062205 100644
--- a/mediacapture-streams/MediaStreamTrack-getSettings.https.html
+++ b/mediacapture-streams/MediaStreamTrack-getSettings.https.html
@@ -1,6 +1,7 @@
<!doctype html>
<title>MediaStreamTrack GetSettings</title>
<p class="instructions">When prompted, accept to share your video stream.</p>
+<meta name=timeout content=long>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
diff --git a/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html b/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html
index edde533..45f3f0a 100644
--- a/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html
+++ b/payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html
@@ -68,7 +68,6 @@
<button onclick="
const expectedAddress = {
country: 'AU',
- regionCode: 'QLD',
addressLine: '55 test st',
city: 'Chapel Hill',
dependentLocality: '',
diff --git a/payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html b/payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html
index 356f30d..c3e2ba7 100644
--- a/payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html
+++ b/payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html
@@ -82,11 +82,6 @@
</button>
</li>
<li>
- <button onclick="retryShowsShippingAddressMember(this, { regionCode: 'REGIONCODE ERROR' });">
- The payment sheet shows "REGIONCODE ERROR" for the shipping address' region code.
- </button>
- </li>
- <li>
<button onclick="retryShowsShippingAddressMember(this, { sortingCode: 'SORTINGCODE ERROR' });">
The payment sheet shows "SORTINGCODE ERROR" for the shipping address' sorting code.
</button>
diff --git a/payment-request/historical.https.html b/payment-request/historical.https.html
index cbd29d4..e681f64 100644
--- a/payment-request/historical.https.html
+++ b/payment-request/historical.https.html
@@ -21,6 +21,9 @@
// https://github.com/w3c/payment-request/pull/765
["languageCode", "PaymentAddress"],
+
+ // https://github.com/w3c/payment-request/pull/823
+ ["regionCode", "PaymentAddress"],
].forEach(([member, interf]) => {
test(() => {
assert_false(member in window[interf].prototype);
diff --git a/quirks/unitless-length/excluded-properties-001.html b/quirks/unitless-length/excluded-properties-001.html
index 2e33cec..09fedcf 100644
--- a/quirks/unitless-length/excluded-properties-001.html
+++ b/quirks/unitless-length/excluded-properties-001.html
@@ -30,6 +30,13 @@
'grid-template-columns',
'grid-template-rows',
'inline-size',
+ 'inset',
+ 'inset-block',
+ 'inset-block-end',
+ 'inset-block-start',
+ 'inset-inline',
+ 'inset-inline-end',
+ 'inset-inline-start',
'margin-block-end',
'margin-block-start',
'margin-inline-end',
diff --git a/quirks/unitless-length/excluded-properties-003.html b/quirks/unitless-length/excluded-properties-003.html
new file mode 100644
index 0000000..4cbe012
--- /dev/null
+++ b/quirks/unitless-length/excluded-properties-003.html
@@ -0,0 +1,42 @@
+<html>
+<head>
+<meta charset="utf-8">
+<title>inset does not support quirky-length</title>
+<link rel="help" href="https://quirks.spec.whatwg.org/#the-unitless-length-quirk">
+<meta name="assert" content="quirky-length is not supported by inset.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+'use strict';
+
+test(() => {
+ const quirky_values = [
+ '1',
+ '1 2px',
+ '1px 2',
+ '1 2',
+ '1 2px 3px',
+ '1px 2 3px',
+ '1px 2px 3',
+ '1 2 3',
+ '1 2px 3px 4px',
+ '1px 2 3px 4px',
+ '1px 2px 3 4px',
+ '1px 2px 3px 4',
+ '1 2 3 4'
+ ];
+
+ target.style['inset'] = '5px 6px 7px 8px';
+
+ for (let value of quirky_values) {
+ target.style['inset'] = value;
+ assert_equals(target.style['inset'], '5px 6px 7px 8px', 'inset rejects quirky length "' + value + '"');
+ }
+}, 'inset does not support quirky length values');
+
+</script>
+</body>
+</html>
diff --git a/resources/testharness.js b/resources/testharness.js
index ed3ffb4..fb86c58 100644
--- a/resources/testharness.js
+++ b/resources/testharness.js
@@ -2135,6 +2135,9 @@
}
} else if (p == "timeout_multiplier") {
this.timeout_multiplier = value;
+ if (this.timeout_length) {
+ this.timeout_length *= this.timeout_multiplier;
+ }
}
}
}
diff --git a/service-workers/service-worker/appcache-ordering-main.https.html b/service-workers/service-worker/appcache-ordering-main.https.html
index 921dae0..a86671c 100644
--- a/service-workers/service-worker/appcache-ordering-main.https.html
+++ b/service-workers/service-worker/appcache-ordering-main.https.html
@@ -5,7 +5,6 @@
<body>
<script>
-var INSTALL_APPCACHE_URL = "resources/appcache-ordering.install.html";
var IS_APPCACHED_URL = "resources/appcache-ordering.is-appcached.html";
var SERVICE_WORKER_SCOPE = "resources/appcache-ordering";
var SERVICE_WORKER_SCRIPT = "resources/empty-worker.js";
@@ -15,31 +14,6 @@
var frames = [];
-// Called by the INSTALL_APPCACHE_URL child frame.
-function notify_appcache_installed(success) {
- if (success)
- resolve_install_appcache();
- else
- reject_install_appcache();
-}
-
-function install_appcache() {
- return new Promise(function(resolve, reject) {
- var frame = document.createElement('iframe');
- frames.push(frame);
- frame.src = INSTALL_APPCACHE_URL;
- document.body.appendChild(frame);
- resolve_install_appcache = function() {
- document.body.removeChild(frame);
- resolve();
- };
- reject_install_appcache = function() {
- document.body.removeChild(frame);
- reject();
- };
- });
-}
-
var resolve_is_appcached = undefined;
// Called by the IS_APPCACHED_URL child frame.
@@ -63,7 +37,7 @@
promise_test(function(t) {
return service_worker_unregister(t, SERVICE_WORKER_SCOPE)
.then(function() {
- return install_appcache();
+ return install_appcache_ordering_manifest();
})
.then(function() {
return is_appcached();
diff --git a/service-workers/service-worker/claim-fetch-with-appcache.https.html b/service-workers/service-worker/claim-fetch-with-appcache.https.html
new file mode 100644
index 0000000..4890a84
--- /dev/null
+++ b/service-workers/service-worker/claim-fetch-with-appcache.https.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<meta charset=utf-8>
+<title></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+
+// This test makes a frame controlled by AppCache, then registers a service
+// worker that calls claim() to control the frame. AppCache should be completely
+// bypassed once the service worker claims the frame.
+
+const fetch_text = async frame => {
+ const response = await
+ frame.contentWindow.fetch('appcache-ordering.is-appcached.js');
+ return await response.text();
+};
+
+const check_is_appcached = async frame => {
+ // This should FALLBACK to ordering.is_appcached.js as in the manifest
+ // if the appcache is effective.
+ const response = await
+ frame.contentWindow.fetch('appcache-ordering.is-appcached404.js');
+ return await response.ok;
+};
+
+promise_test(async t => {
+ const scope = 'resources/';
+ const script = 'resources/claim-worker.js';
+
+ await install_appcache_ordering_manifest();
+
+ // Create the test iframe.
+ const frame = await with_iframe('resources/blank.html');
+ t.add_cleanup(async () => {
+ if (frame) frame.remove();
+ return service_worker_unregister(t, scope);
+ });
+
+ // Check that the appcache controls the frame.
+ assert_equals(await check_is_appcached(frame), true,
+ 'AppCache should be present');
+
+ // Check the controller and test with fetch.
+ assert_equals(frame.contentWindow.navigator.controller, undefined,
+ 'Should have no controller.');
+ assert_equals(await fetch_text(frame), 'var is_appcached = true;\n',
+ 'fetch() should not be intercepted.');
+
+ // Register a service worker.
+ let registration = await service_worker_unregister_and_register(t, script, scope);
+ const worker = registration.installing;
+ await wait_for_state(t, worker, 'activated');
+
+ // Let the service worker claim the iframe.
+ const channel = new MessageChannel();
+ const check_message = new Promise(resolve => {
+ channel.port1.onmessage = async e => {
+ assert_equals(e.data, 'PASS', 'Worker call to claim() should fulfill.');
+ resolve();
+ };
+ });
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ await check_message;
+
+ // Check that the appcache does NOT control the frame.
+ assert_equals(await check_is_appcached(frame), false,
+ 'AppCache should not be present');
+
+ // Check the controller and test with fetch.
+ registration = await
+ frame.contentWindow.navigator.serviceWorker.getRegistration(scope);
+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
+ registration.active, 'iframe should be claimed.');
+ assert_equals(await fetch_text(frame), 'Intercepted!',
+ 'fetch() should be intercepted.');
+}, 'fetch() should be intercepted after the client is claimed.')
+
+</script>
+</body>
diff --git a/service-workers/service-worker/resources/appcache-ordering.manifest b/service-workers/service-worker/resources/appcache-ordering.manifest
index 0deed0e..e6597cc 100644
--- a/service-workers/service-worker/resources/appcache-ordering.manifest
+++ b/service-workers/service-worker/resources/appcache-ordering.manifest
@@ -1,6 +1,7 @@
CACHE MANIFEST
appcache-ordering.is-appcached.html
+blank.html
FALLBACK:
appcache-ordering.is-appcached404.js appcache-ordering.is-appcached.js
diff --git a/service-workers/service-worker/resources/claim-worker.js b/service-workers/service-worker/resources/claim-worker.js
index 53f210c..1800407 100644
--- a/service-workers/service-worker/resources/claim-worker.js
+++ b/service-workers/service-worker/resources/claim-worker.js
@@ -14,5 +14,6 @@
});
self.addEventListener('fetch', function(event) {
- event.respondWith(new Response('Intercepted!'));
-});
+ if (!/404/.test(event.request.url))
+ event.respondWith(new Response('Intercepted!'));
+ });
diff --git a/service-workers/service-worker/resources/test-helpers.sub.js b/service-workers/service-worker/resources/test-helpers.sub.js
index 7efde35..1410131 100644
--- a/service-workers/service-worker/resources/test-helpers.sub.js
+++ b/service-workers/service-worker/resources/test-helpers.sub.js
@@ -276,3 +276,33 @@
await wait_for_state(t, registration.installing, 'activated');
await registration.unregister();
}
+
+// This installs resources/appcache-ordering.manifest.
+function install_appcache_ordering_manifest() {
+ let resolve_install_appcache;
+ let reject_install_appcache;
+
+ // This is notified by the child iframe, i.e. appcache-ordering.install.html,
+ // that's to be created below.
+ window.notify_appcache_installed = success => {
+ if (success)
+ resolve_install_appcache();
+ else
+ reject_install_appcache();
+ };
+
+ return new Promise((resolve, reject) => {
+ const frame = document.createElement('iframe');
+ frame.src = 'resources/appcache-ordering.install.html';
+ document.body.appendChild(frame);
+ resolve_install_appcache = function() {
+ document.body.removeChild(frame);
+ resolve();
+ };
+ reject_install_appcache = function() {
+ document.body.removeChild(frame);
+ reject();
+ };
+ });
+}
+
diff --git a/signed-exchange/resources/sxg-util.js b/signed-exchange/resources/sxg-util.js
index 0d0e263..7d592ea 100644
--- a/signed-exchange/resources/sxg-util.js
+++ b/signed-exchange/resources/sxg-util.js
@@ -41,3 +41,27 @@
function innerURLOrigin() {
return 'https://127.0.0.1:8444';
}
+
+function runReferrerTests(test_cases) {
+ for (const i in test_cases) {
+ const test_case = test_cases[i];
+ promise_test(async (t) => {
+ const sxgUrl = test_case.origin + '/signed-exchange/resources/sxg/' +
+ test_case.sxg;
+ const message =
+ await openSXGInIframeAndWaitForMessage(
+ t, sxgUrl, test_case.referrerPolicy);
+ assert_false(message.is_fallback);
+ assert_equals(message.referrer, test_case.expectedReferrer);
+
+ const invalidSxgUrl =
+ test_case.origin + '/signed-exchange/resources/sxg/invalid-' +
+ test_case.sxg;
+ const fallbackMessage =
+ await openSXGInIframeAndWaitForMessage(
+ t, invalidSxgUrl, test_case.referrerPolicy);
+ assert_true(fallbackMessage.is_fallback);
+ assert_equals(fallbackMessage.referrer, test_case.expectedReferrer);
+ }, 'Referrer of SignedHTTPExchange test : ' + JSON.stringify(test_case));
+ }
+}
diff --git a/signed-exchange/sxg-referrer-policy-header.tentative.https.html b/signed-exchange/sxg-referrer-policy-header.tentative.https.html
new file mode 100644
index 0000000..5dff6af
--- /dev/null
+++ b/signed-exchange/sxg-referrer-policy-header.tentative.https.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<title>Referrer-Policy header in outer SXG response</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="./resources/sxg-util.js"></script>
+<body>
+<script>
+(() => {
+ const SAME_ORIGIN = get_host_info().HTTPS_ORIGIN;
+ const SAME_ORIGIN_SXG = 'sxg-referrer-same-origin.sxg';
+ const TEST_CASES = [
+ // Referrer-Policy header in outer SXG response.
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,no-referrer)',
+ referrerPolicy: undefined,
+ expectedReferrer: ''
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG +
+ '?pipe=header(Referrer-Policy,no-referrer-when-downgrade)',
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,origin)',
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,same-origin)',
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,strict-origin)',
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG +
+ '?pipe=header(Referrer-Policy,strict-origin-when-cross-origin)',
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,unsafe-url)',
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.href
+ },
+ ];
+ runReferrerTests(TEST_CASES);
+})();
+</script>
+</body>
diff --git a/signed-exchange/sxg-referrer-remote-physical-remote-logical.tentative.https.html b/signed-exchange/sxg-referrer-remote-physical-remote-logical.tentative.https.html
new file mode 100644
index 0000000..c2870fd
--- /dev/null
+++ b/signed-exchange/sxg-referrer-remote-physical-remote-logical.tentative.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<title>Referrer of SignedHTTPExchange(physical:remote origin, logical:remote origin)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="./resources/sxg-util.js"></script>
+<body>
+<script>
+(() => {
+ const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
+ const REMOTE_ORIGIN_SXG = 'sxg-referrer-remote-origin.sxg';
+ const TEST_CASES = [
+ // Physical origin = remote origin. Logical origin = remote origin.
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'no-referrer',
+ expectedReferrer: ''
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'no-referrer-when-downgrade',
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'same-origin',
+ expectedReferrer: ''
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'strict-origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'strict-origin-when-cross-origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'unsafe-url',
+ expectedReferrer: document.location.href
+ },
+ ];
+ runReferrerTests(TEST_CASES);
+})();
+</script>
+</body>
diff --git a/signed-exchange/sxg-referrer-remote-physical-same-logical.tentative.https.html b/signed-exchange/sxg-referrer-remote-physical-same-logical.tentative.https.html
new file mode 100644
index 0000000..b3c77d1
--- /dev/null
+++ b/signed-exchange/sxg-referrer-remote-physical-same-logical.tentative.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<title>Referrer of SignedHTTPExchange(physical:remote origin, logical:same origin)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="./resources/sxg-util.js"></script>
+<body>
+<script>
+(() => {
+ const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
+ const SAME_ORIGIN_SXG = 'sxg-referrer-same-origin.sxg';
+ const TEST_CASES = [
+ // Physical origin = remote origin. Logical origin = same origin.
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'no-referrer',
+ expectedReferrer: ''
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'no-referrer-when-downgrade',
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'same-origin',
+ expectedReferrer: ''
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'strict-origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'strict-origin-when-cross-origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: REMOTE_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'unsafe-url',
+ expectedReferrer: document.location.href
+ },
+ ];
+ runReferrerTests(TEST_CASES);
+})();
+</script>
+</body>
diff --git a/signed-exchange/sxg-referrer-same-physical-remote-logical.tentative.https.html b/signed-exchange/sxg-referrer-same-physical-remote-logical.tentative.https.html
new file mode 100644
index 0000000..8a6cdd9
--- /dev/null
+++ b/signed-exchange/sxg-referrer-same-physical-remote-logical.tentative.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<title>Referrer of SignedHTTPExchange(physical:same origin, logical:remote origin)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="./resources/sxg-util.js"></script>
+<body>
+<script>
+(() => {
+ const SAME_ORIGIN = get_host_info().HTTPS_ORIGIN;
+ const REMOTE_ORIGIN_SXG = 'sxg-referrer-remote-origin.sxg';
+ const TEST_CASES = [
+ // Physical origin = same origin. Logical origin = remote origin.
+ {
+ origin: SAME_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'no-referrer',
+ expectedReferrer: ''
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'no-referrer-when-downgrade',
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'same-origin',
+ expectedReferrer: ''
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'strict-origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'strict-origin-when-cross-origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: REMOTE_ORIGIN_SXG,
+ referrerPolicy: 'unsafe-url',
+ expectedReferrer: document.location.href
+ },
+ ];
+ runReferrerTests(TEST_CASES);
+})();
+</script>
+</body>
diff --git a/signed-exchange/sxg-referrer-same-physical-same-logical.tentative.https.html b/signed-exchange/sxg-referrer-same-physical-same-logical.tentative.https.html
new file mode 100644
index 0000000..8891716
--- /dev/null
+++ b/signed-exchange/sxg-referrer-same-physical-same-logical.tentative.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<title>Referrer of SignedHTTPExchange(physical:same origin, logical:same origin)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="./resources/sxg-util.js"></script>
+<body>
+<script>
+(() => {
+ const SAME_ORIGIN = get_host_info().HTTPS_ORIGIN;
+ const SAME_ORIGIN_SXG = 'sxg-referrer-same-origin.sxg';
+ const TEST_CASES = [
+ // Physical origin = same origin. Logical origin = same origin.
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: undefined,
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'no-referrer',
+ expectedReferrer: ''
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'no-referrer-when-downgrade',
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'same-origin',
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'strict-origin',
+ expectedReferrer: document.location.origin + '/'
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'strict-origin-when-cross-origin',
+ expectedReferrer: document.location.href
+ },
+ {
+ origin: SAME_ORIGIN,
+ sxg: SAME_ORIGIN_SXG,
+ referrerPolicy: 'unsafe-url',
+ expectedReferrer: document.location.href
+ },
+ ];
+ runReferrerTests(TEST_CASES);
+})();
+</script>
+</body>
diff --git a/signed-exchange/sxg-referrer.tentative.https.html b/signed-exchange/sxg-referrer.tentative.https.html
deleted file mode 100644
index 3be9b1f..0000000
--- a/signed-exchange/sxg-referrer.tentative.https.html
+++ /dev/null
@@ -1,284 +0,0 @@
-<!DOCTYPE html>
-<title>Referrer of SignedHTTPExchange</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/common/get-host-info.sub.js"></script>
-<script src="./resources/sxg-util.js"></script>
-<body>
-<script>
-(() => {
- const SAME_ORIGIN = get_host_info().HTTPS_ORIGIN;
- const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
- const SAME_ORIGIN_SXG = 'sxg-referrer-same-origin.sxg';
- const REMOTE_ORIGIN_SXG = 'sxg-referrer-remote-origin.sxg';
- const TEST_CASES = [
- // Physical origin = same origin. Logical origin = same origin.
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: undefined,
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'no-referrer',
- expectedReferrer: ''
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'no-referrer-when-downgrade',
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'same-origin',
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'strict-origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'strict-origin-when-cross-origin',
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'unsafe-url',
- expectedReferrer: document.location.href
- },
-
- // Physical origin = same origin. Logical origin = remote origin.
- {
- origin: SAME_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: undefined,
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'no-referrer',
- expectedReferrer: ''
- },
- {
- origin: SAME_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'no-referrer-when-downgrade',
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: SAME_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'same-origin',
- expectedReferrer: ''
- },
- {
- origin: SAME_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'strict-origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: SAME_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'strict-origin-when-cross-origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: SAME_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'unsafe-url',
- expectedReferrer: document.location.href
- },
-
- // Physical origin = remote origin. Logical origin = same origin.
- {
- origin: REMOTE_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: undefined,
- expectedReferrer: document.location.href
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'no-referrer',
- expectedReferrer: ''
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'no-referrer-when-downgrade',
- expectedReferrer: document.location.href
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'same-origin',
- expectedReferrer: ''
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'strict-origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'strict-origin-when-cross-origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: SAME_ORIGIN_SXG,
- referrerPolicy: 'unsafe-url',
- expectedReferrer: document.location.href
- },
-
- // Physical origin = remote origin. Logical origin = remote origin.
- {
- origin: REMOTE_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: undefined,
- expectedReferrer: document.location.href
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'no-referrer',
- expectedReferrer: ''
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'no-referrer-when-downgrade',
- expectedReferrer: document.location.href
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'same-origin',
- expectedReferrer: ''
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'strict-origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'strict-origin-when-cross-origin',
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: REMOTE_ORIGIN,
- sxg: REMOTE_ORIGIN_SXG,
- referrerPolicy: 'unsafe-url',
- expectedReferrer: document.location.href
- },
-
- // Referrer-Policy header in outer SXG response.
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,no-referrer)',
- referrerPolicy: undefined,
- expectedReferrer: ''
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG +
- '?pipe=header(Referrer-Policy,no-referrer-when-downgrade)',
- referrerPolicy: undefined,
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,origin)',
- referrerPolicy: undefined,
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,same-origin)',
- referrerPolicy: undefined,
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,strict-origin)',
- referrerPolicy: undefined,
- expectedReferrer: document.location.origin + '/'
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG +
- '?pipe=header(Referrer-Policy,strict-origin-when-cross-origin)',
- referrerPolicy: undefined,
- expectedReferrer: document.location.href
- },
- {
- origin: SAME_ORIGIN,
- sxg: SAME_ORIGIN_SXG + '?pipe=header(Referrer-Policy,unsafe-url)',
- referrerPolicy: undefined,
- expectedReferrer: document.location.href
- },
- ];
- for (const i in TEST_CASES) {
- const test_case = TEST_CASES[i];
- promise_test(async (t) => {
- const sxgUrl = test_case.origin + '/signed-exchange/resources/sxg/' +
- test_case.sxg;
- const message =
- await openSXGInIframeAndWaitForMessage(
- t, sxgUrl, test_case.referrerPolicy);
- assert_false(message.is_fallback);
- assert_equals(message.referrer, test_case.expectedReferrer);
-
- const invalidSxgUrl =
- test_case.origin + '/signed-exchange/resources/sxg/invalid-' +
- test_case.sxg;
- const fallbackMessage =
- await openSXGInIframeAndWaitForMessage(
- t, invalidSxgUrl, test_case.referrerPolicy);
- assert_true(fallbackMessage.is_fallback);
- assert_equals(fallbackMessage.referrer, test_case.expectedReferrer);
- }, 'Referrer of SignedHTTPExchange test : ' + JSON.stringify(test_case));
- }
-})();
-</script>
-</body>
diff --git a/storage/estimate-usage-details-application-cache.https.tentative.html b/storage/estimate-usage-details-application-cache.https.tentative.html
new file mode 100644
index 0000000..464a998
--- /dev/null
+++ b/storage/estimate-usage-details-application-cache.https.tentative.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<html>
+<title>Quota Estimate: usage details reflect application cache changes.</title>
+<meta charset='utf-8'>
+<link rel='author' href='jarrydg@chromium.org' title='Jarryd Goodman'>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='../cookie-store/resources/helpers.js'></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+ let estimate = await navigator.storage.estimate();
+
+ const usageBeforeCreate = estimate.usageDetails.applicationCache || 0;
+
+ const iframe = await
+ createIframe('./resources/iframe_with_appcache_manifest.html', t);
+ await waitForMessage();
+
+ estimate = await navigator.storage.estimate();
+ assert_true('applicationCache' in estimate.usageDetails);
+ const usageAfterCreate = estimate.usageDetails.applicationCache;
+
+ assert_greater_than(
+ usageAfterCreate, usageBeforeCreate);
+}, 'estimate() shows usage increase after app is cached');
+</script>
+</html>
diff --git a/storage/estimate-usage-details-caches.https.tentative.any.js b/storage/estimate-usage-details-caches.https.tentative.any.js
new file mode 100644
index 0000000..bf889f8
--- /dev/null
+++ b/storage/estimate-usage-details-caches.https.tentative.any.js
@@ -0,0 +1,20 @@
+// META: title=StorageManager: estimate() for caches
+
+promise_test(async t => {
+ let estimate = await navigator.storage.estimate();
+
+ const cachesUsageBeforeCreate = estimate.usageDetails.caches || 0;
+
+ const cacheName = 'testCache';
+ const cache = await caches.open(cacheName);
+ t.add_cleanup(() => caches.delete(cacheName));
+
+ await cache.put('/test.json', new Response('x'.repeat(1024*1024)));
+
+ estimate = await navigator.storage.estimate();
+ assert_true('caches' in estimate.usageDetails);
+ const cachesUsageAfterPut = estimate.usageDetails.caches;
+ assert_greater_than(
+ cachesUsageAfterPut, cachesUsageBeforeCreate,
+ 'estimated usage should increase after value is stored');
+}, 'estimate() shows usage increase after large value is stored');
diff --git a/storage/estimate-usage-details.https.tentative.any.js b/storage/estimate-usage-details.https.tentative.any.js
new file mode 100644
index 0000000..2a1cea5
--- /dev/null
+++ b/storage/estimate-usage-details.https.tentative.any.js
@@ -0,0 +1,12 @@
+// META: title=StorageManager: estimate() should have usage details
+
+promise_test(async t => {
+ const estimate = await navigator.storage.estimate();
+ assert_equals(typeof estimate, 'object');
+ assert_true('usage' in estimate);
+ assert_equals(typeof estimate.usage, 'number');
+ assert_true('quota' in estimate);
+ assert_equals(typeof estimate.quota, 'number');
+ assert_true('usageDetails' in estimate);
+ assert_equals(typeof estimate.usageDetails, 'object');
+}, 'estimate() resolves to dictionary with members, including usageDetails');
diff --git a/storage/resources/appcache.manifest b/storage/resources/appcache.manifest
new file mode 100644
index 0000000..ce90baf
--- /dev/null
+++ b/storage/resources/appcache.manifest
@@ -0,0 +1,3 @@
+CACHE MANIFEST
+# iframe_with_appcache_manifest.html references this manifest to get cached in
+# AppCache.
diff --git a/storage/resources/iframe_with_appcache_manifest.html b/storage/resources/iframe_with_appcache_manifest.html
new file mode 100644
index 0000000..8365ce4
--- /dev/null
+++ b/storage/resources/iframe_with_appcache_manifest.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html manifest="appcache.manifest">
+<title>Iframe that will be cached using application cache.</title>
+<meta charset='utf-8'>
+<link rel='author' href='jarrydg@chromium.org' title='Jarryd Goodman'>
+<script>
+(async () => {
+ const initPromise = new Promise(resolve => {
+ applicationCache.addEventListener('cached', resolve);
+ applicationCache.addEventListener('noupdate', resolve);
+ });
+ await initPromise;
+
+ window.parent.postMessage('document cached');
+})();
+</script>
+</html>
diff --git a/tools/ci/check_stability.py b/tools/ci/check_stability.py
deleted file mode 100644
index a71e095..0000000
--- a/tools/ci/check_stability.py
+++ /dev/null
@@ -1,318 +0,0 @@
-from __future__ import print_function
-
-import argparse
-import logging
-import os
-import subprocess
-import sys
-from ConfigParser import SafeConfigParser
-
-here = os.path.dirname(__file__)
-wpt_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir))
-sys.path.insert(0, wpt_root)
-
-from tools.wpt import run as wptrun, testfiles
-from tools.wpt.testfiles import get_git_cmd
-from tools.wpt.virtualenv import Virtualenv
-from tools.wpt.utils import Kwargs
-from tools.wpt.run import create_parser, setup_wptrunner
-from tools.wpt import markdown
-from tools import localpaths # noqa: F401
-
-logger = None
-run_step, write_inconsistent, write_slow_tests, write_results = None, None, None, None
-wptrunner = None
-
-def setup_logging():
- """Set up basic debug logger."""
- global logger
- logger = logging.getLogger(here)
- handler = logging.StreamHandler(sys.stdout)
- formatter = logging.Formatter(logging.BASIC_FORMAT, None)
- handler.setFormatter(formatter)
- logger.addHandler(handler)
- logger.setLevel(logging.DEBUG)
- wptrun.setup_logging({})
-
-def do_delayed_imports():
- global wptrunner, run_step, write_inconsistent, write_slow_tests, write_results
- from wptrunner import wptrunner
- from wptrunner.stability import run_step, write_inconsistent, write_slow_tests, write_results
-
-
-class TravisFold(object):
- """Context for TravisCI folding mechanism. Subclasses object.
-
- See: https://blog.travis-ci.com/2013-05-22-improving-build-visibility-log-folds/
- """
-
- def __init__(self, name):
- """Register TravisCI folding section name."""
- self.name = name
-
- def __enter__(self):
- """Emit fold start syntax."""
- print("travis_fold:start:%s" % self.name, file=sys.stderr)
-
- def __exit__(self, type, value, traceback):
- """Emit fold end syntax."""
- print("travis_fold:end:%s" % self.name, file=sys.stderr)
-
-
-class FilteredIO(object):
- """Wrap a file object, invoking the provided callback for every call to
- `write` and only proceeding with the operation when that callback returns
- True."""
- def __init__(self, original, on_write):
- self.original = original
- self.on_write = on_write
-
- def __getattr__(self, name):
- return getattr(self.original, name)
-
- def disable(self):
- self.write = lambda msg: None
-
- def write(self, msg):
- encoded = msg.encode("utf8", "backslashreplace").decode("utf8")
- if self.on_write(self.original, encoded) is True:
- self.original.write(encoded)
-
-
-def replace_streams(capacity, warning_msg):
- # Value must be boxed to support modification from inner function scope
- count = [0]
- capacity -= 2 + len(warning_msg)
- stderr = sys.stderr
-
- def on_write(handle, msg):
- length = len(msg)
- count[0] += length
-
- if count[0] > capacity:
- wrapped_stdout.disable()
- wrapped_stderr.disable()
- handle.write(msg[0:capacity - count[0]])
- handle.flush()
- stderr.write("\n%s\n" % warning_msg)
- return False
-
- return True
-
- # Store local references to the replaced streams to guard against the case
- # where other code replace the global references.
- sys.stdout = wrapped_stdout = FilteredIO(sys.stdout, on_write)
- sys.stderr = wrapped_stderr = FilteredIO(sys.stderr, on_write)
-
-
-def call(*args):
- """Log terminal command, invoke it as a subprocess.
-
- Returns a bytestring of the subprocess output if no error.
- """
- logger.debug(" ".join(args))
- try:
- return subprocess.check_output(args)
- except subprocess.CalledProcessError as e:
- logger.critical("%s exited with return code %i" %
- (e.cmd, e.returncode))
- logger.critical(e.output)
- raise
-
-
-def fetch_wpt(user, *args):
- git = get_git_cmd(wpt_root)
- git("fetch", "https://github.com/%s/web-platform-tests.git" % user, *args)
-
-
-def get_sha1():
- """ Get and return sha1 of current git branch HEAD commit."""
- git = get_git_cmd(wpt_root)
- return git("rev-parse", "HEAD").strip()
-
-
-def deepen_checkout(user):
- """Convert from a shallow checkout to a full one"""
- fetch_args = [user, "+refs/heads/*:refs/remotes/origin/*"]
- if os.path.exists(os.path.join(wpt_root, ".git", "shallow")):
- fetch_args.insert(1, "--unshallow")
- fetch_wpt(*fetch_args)
-
-
-def get_parser():
- """Create and return script-specific argument parser."""
- description = """Detect instabilities in new tests by executing tests
- repeatedly and comparing results between executions."""
- parser = argparse.ArgumentParser(description=description)
- parser.add_argument("--user",
- action="store",
- # Travis docs say do not depend on USER env variable.
- # This is a workaround to get what should be the same value
- default=os.environ.get("TRAVIS_REPO_SLUG", "w3c").split('/')[0],
- help="Travis user name")
- parser.add_argument("--output-bytes",
- action="store",
- type=int,
- help="Maximum number of bytes to write to standard output/error")
- parser.add_argument("--metadata",
- dest="metadata_root",
- action="store",
- default=wpt_root,
- help="Directory that will contain MANIFEST.json")
- parser.add_argument("--config-file",
- action="store",
- type=str,
- help="Location of ini-formatted configuration file",
- default="check_stability.ini")
- parser.add_argument("--rev",
- action="store",
- default=None,
- help="Commit range to use")
- return parser
-
-
-def pr():
- pr = os.environ.get("TRAVIS_PULL_REQUEST", "false")
- return pr if pr != "false" else None
-
-
-def get_changed_files(manifest_path, rev, ignore_changes):
- if not rev:
- branch_point = testfiles.branch_point()
- revish = "%s..HEAD" % branch_point
- else:
- revish = rev
-
- files_changed, files_ignored = testfiles.files_changed(revish, ignore_changes)
-
- if files_ignored:
- logger.info("Ignoring %s changed files:\n%s" %
- (len(files_ignored), "".join(" * %s\n" % item for item in files_ignored)))
-
- tests_changed, files_affected = testfiles.affected_testfiles(files_changed,
- manifest_path=manifest_path)
-
- return tests_changed, files_affected
-
-
-def main():
- """Perform check_stability functionality and return exit code."""
-
- venv = Virtualenv(os.environ.get("VIRTUAL_ENV", os.path.join(wpt_root, "_venv")))
- venv.install_requirements(os.path.join(wpt_root, "tools", "wptrunner", "requirements.txt"))
-
- args, wpt_args = get_parser().parse_known_args()
- return run(venv, wpt_args, **vars(args))
-
-
-def run(venv, wpt_args, **kwargs):
- do_delayed_imports()
-
- setup_logging()
-
- retcode = 0
-
- wpt_args = create_parser().parse_args(wpt_args)
-
- with open(kwargs["config_file"], 'r') as config_fp:
- config = SafeConfigParser()
- config.readfp(config_fp)
- ignore_changes = set(config.get("file detection", "ignore_changes").split())
-
- if kwargs["output_bytes"] is not None:
- replace_streams(kwargs["output_bytes"],
- "Log reached capacity (%s bytes); output disabled." % kwargs["output_bytes"])
-
-
- wpt_args.metadata_root = kwargs["metadata_root"]
- try:
- os.makedirs(wpt_args.metadata_root)
- except OSError:
- pass
-
- pr_number = pr()
-
- with TravisFold("browser_setup"):
- logger.info(markdown.format_comment_title(wpt_args.product))
-
- if pr is not None:
- deepen_checkout(kwargs["user"])
-
- # Ensure we have a branch called "master"
- fetch_wpt(kwargs["user"], "master:master")
-
- head_sha1 = get_sha1()
- logger.info("Testing web-platform-tests at revision %s" % head_sha1)
-
- wpt_kwargs = Kwargs(vars(wpt_args))
-
- if not wpt_kwargs["test_list"]:
- manifest_path = os.path.join(wpt_kwargs["metadata_root"], "MANIFEST.json")
- tests_changed, files_affected = get_changed_files(manifest_path, kwargs["rev"],
- ignore_changes)
-
- if not (tests_changed or files_affected):
- logger.info("No tests changed")
- return 0
-
- if tests_changed:
- logger.debug("Tests changed:\n%s" % "".join(" * %s\n" % item for item in tests_changed))
-
- if files_affected:
- logger.debug("Affected tests:\n%s" % "".join(" * %s\n" % item for item in files_affected))
-
- wpt_kwargs["test_list"] = list(tests_changed | files_affected)
-
- do_delayed_imports()
-
- wpt_kwargs["prompt"] = False
- wpt_kwargs["install_browser"] = wpt_kwargs["product"].split(":")[0] == "firefox"
-
- wpt_kwargs["pause_after_test"] = False
- wpt_kwargs["verify_log_full"] = False
- if wpt_kwargs["repeat"] == 1:
- wpt_kwargs["repeat"] = 10
- wpt_kwargs["headless"] = False
-
- wpt_kwargs["log_tbpl"] = [sys.stdout]
-
- wpt_kwargs = setup_wptrunner(venv, **wpt_kwargs)
-
- logger.info("Using binary %s" % wpt_kwargs["binary"])
-
-
- with TravisFold("running_tests"):
- logger.info("Starting tests")
-
- wpt_logger = wptrunner.logger
- results, inconsistent, slow, iterations = run_step(wpt_logger, wpt_kwargs["repeat"], True, {}, **wpt_kwargs)
-
- if results:
- if inconsistent:
- write_inconsistent(logger.error, inconsistent, iterations)
- retcode = 2
- elif slow:
- write_slow_tests(logger.error, slow)
- retcode = 2
- else:
- logger.info("All results were stable\n")
- with TravisFold("full_results"):
- write_results(logger.info, results, iterations,
- pr_number=pr_number,
- use_details=True)
- else:
- logger.info("No tests run.")
- # Be conservative and only return errors when we know for sure tests are changed.
- if tests_changed:
- retcode = 3
-
- return retcode
-
-
-if __name__ == "__main__":
- try:
- sys.exit(main())
- except Exception:
- import traceback
- traceback.print_exc()
- sys.exit(1)
diff --git a/tools/ci/commands.json b/tools/ci/commands.json
index 361c9e4..841fd85 100644
--- a/tools/ci/commands.json
+++ b/tools/ci/commands.json
@@ -6,20 +6,6 @@
"help": "List test jobs that should run for a set of commits",
"virtualenv": false
},
- "check-stability": {
- "path": "check_stability.py",
- "script": "run",
- "parser": "get_parser",
- "parse_known": true,
- "help": "Check test stability",
- "virtualenv": true,
- "install": [
- "requests"
- ],
- "requirements": [
- "../wptrunner/requirements.txt"
- ]
- },
"make-hosts-file": {
"path": "make_hosts_file.py",
"script": "run",
diff --git a/tools/ci/start.sh b/tools/ci/start.sh
index 9f621b2..580bfb9 100644
--- a/tools/ci/start.sh
+++ b/tools/ci/start.sh
@@ -28,3 +28,4 @@
fi
sudo Xvfb $DISPLAY -screen 0 ${SCREEN_WIDTH}x${SCREEN_HEIGHT}x${SCREEN_DEPTH} &
+sudo fluxbox -display $DISPLAY &
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 20f6ef2..53564ac 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -11,6 +11,7 @@
ca-certificates \
dbus-x11 \
earlyoom \
+ fluxbox \
gdebi \
git \
locales \
diff --git a/tools/requirements_flake8.txt b/tools/requirements_flake8.txt
index d2e7dd6..00d182e 100644
--- a/tools/requirements_flake8.txt
+++ b/tools/requirements_flake8.txt
@@ -1,4 +1,4 @@
flake8==3.6.0
pycodestyle==2.4.0
-pyflakes==2.0.0
+pyflakes==2.1.0
pep8-naming==0.7.0
diff --git a/tools/wpt/tests/test_wpt.py b/tools/wpt/tests/test_wpt.py
index bf6250f..1ddac67 100644
--- a/tools/wpt/tests/test_wpt.py
+++ b/tools/wpt/tests/test_wpt.py
@@ -412,6 +412,5 @@
# The following commands are slow running and used implicitly in other CI
# jobs, so we skip them here:
-# wpt check-stability
# wpt manifest
# wpt lint
diff --git a/tools/wptrunner/wptrunner/browsers/firefox.py b/tools/wptrunner/wptrunner/browsers/firefox.py
index 3b5c96c..67d5b6e 100644
--- a/tools/wptrunner/wptrunner/browsers/firefox.py
+++ b/tools/wptrunner/wptrunner/browsers/firefox.py
@@ -76,6 +76,7 @@
"certutil_binary": kwargs["certutil_binary"],
"ca_certificate_path": config.ssl_config["ca_cert_path"],
"e10s": kwargs["gecko_e10s"],
+ "lsan_dir": kwargs["lsan_dir"],
"stackfix_dir": kwargs["stackfix_dir"],
"binary_args": kwargs["binary_args"],
"timeout_multiplier": get_timeout_multiplier(test_type,
@@ -181,7 +182,7 @@
def __init__(self, logger, binary, prefs_root, test_type, extra_prefs=None, debug_info=None,
symbols_path=None, stackwalk_binary=None, certutil_binary=None,
- ca_certificate_path=None, e10s=False, stackfix_dir=None,
+ ca_certificate_path=None, e10s=False, lsan_dir=None, stackfix_dir=None,
binary_args=None, timeout_multiplier=None, leak_check=False, asan=False,
stylo_threads=1, chaos_mode_flags=None, config=None, headless=None, **kwargs):
Browser.__init__(self, logger)
@@ -210,6 +211,7 @@
self.init_timeout = self.init_timeout * timeout_multiplier
self.asan = asan
+ self.lsan_dir = lsan_dir
self.lsan_allowed = None
self.lsan_max_stack_depth = None
self.leak_check = leak_check
@@ -243,7 +245,7 @@
env = test_environment(xrePath=os.path.dirname(self.binary),
debugger=self.debug_info is not None,
log=self.logger,
- lsanPath=self.prefs_root)
+ lsanPath=self.lsan_dir)
env["STYLO_THREADS"] = str(self.stylo_threads)
if self.chaos_mode_flags is not None:
diff --git a/tools/wptrunner/wptrunner/metadata.py b/tools/wptrunner/wptrunner/metadata.py
index 94560cd..b170fc6 100644
--- a/tools/wptrunner/wptrunner/metadata.py
+++ b/tools/wptrunner/wptrunner/metadata.py
@@ -479,7 +479,7 @@
prop = prop_intern.get((packed & 0xF000) >> 12)
value_idx = (packed & 0x0F00) >> 8
- if value_idx is 0:
+ if value_idx == 0:
value = self.raw_data[idx]
else:
value = status_intern.get(value_idx)
diff --git a/tools/wptrunner/wptrunner/wptcommandline.py b/tools/wptrunner/wptrunner/wptcommandline.py
index 8443a01..0a3a8c2 100644
--- a/tools/wptrunner/wptrunner/wptcommandline.py
+++ b/tools/wptrunner/wptrunner/wptcommandline.py
@@ -256,6 +256,8 @@
help="Run tests without electrolysis preferences")
gecko_group.add_argument("--stackfix-dir", dest="stackfix_dir", action="store",
help="Path to directory containing assertion stack fixing scripts")
+ gecko_group.add_argument("--lsan-dir", dest="lsan_dir", action="store",
+ help="Path to directory containing LSAN suppressions file")
gecko_group.add_argument("--setpref", dest="extra_prefs", action='append',
default=[], metavar="PREF=VALUE",
help="Defines an extra user preference (overrides those in prefs_root)")
@@ -527,6 +529,9 @@
if kwargs["reftest_internal"] is None:
kwargs["reftest_internal"] = True
+ if kwargs["lsan_dir"] is None:
+ kwargs["lsan_dir"] = kwargs["prefs_root"]
+
return kwargs
diff --git a/wake-lock/wakelock-supported-by-feature-policy.html b/wake-lock/wakelock-supported-by-feature-policy.html
new file mode 100644
index 0000000..d6289ff
--- /dev/null
+++ b/wake-lock/wakelock-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that wake-lock is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://w3c.github.io/wake-lock/#dfn-wake-lock-feature">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('wake-lock', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise wake-lock.');
+</script>
diff --git a/webdriver/tests/new_window/new_tab.py b/webdriver/tests/new_window/new_tab.py
index fbb249f..0bf9449 100644
--- a/webdriver/tests/new_window/new_tab.py
+++ b/webdriver/tests/new_window/new_tab.py
@@ -26,7 +26,7 @@
value = assert_success(response)
assert value["type"] == "tab"
- session.handle = value["handle"]
+ session.window_handle = value["handle"]
assert session.url == "about:blank"
@@ -35,7 +35,7 @@
value = assert_success(response)
assert value["type"] == "tab"
- session.handle = value["handle"]
+ session.window_handle = value["handle"]
assert window_name(session) == ""
@@ -44,5 +44,5 @@
value = assert_success(response)
assert value["type"] == "tab"
- session.handle = value["handle"]
+ session.window_handle = value["handle"]
assert opener(session) is None
diff --git a/webdriver/tests/new_window/new_window.py b/webdriver/tests/new_window/new_window.py
index eb4db67..8b12248 100644
--- a/webdriver/tests/new_window/new_window.py
+++ b/webdriver/tests/new_window/new_window.py
@@ -26,7 +26,7 @@
value = assert_success(response)
assert value["type"] == "window"
- session.handle = value["handle"]
+ session.window_handle = value["handle"]
assert session.url == "about:blank"
@@ -35,7 +35,7 @@
value = assert_success(response)
assert value["type"] == "window"
- session.handle = value["handle"]
+ session.window_handle = value["handle"]
assert window_name(session) == ""
@@ -44,5 +44,5 @@
value = assert_success(response)
assert value["type"] == "window"
- session.handle = value["handle"]
+ session.window_handle = value["handle"]
assert opener(session) is None
diff --git a/webrtc-quic/RTCQuicTransport.https.html b/webrtc-quic/RTCQuicTransport.https.html
index c64ed6a..82427e6 100644
--- a/webrtc-quic/RTCQuicTransport.https.html
+++ b/webrtc-quic/RTCQuicTransport.https.html
@@ -5,6 +5,7 @@
<script src="/resources/testharnessreport.js"></script>
<script src="../webrtc/RTCIceTransport-extension-helper.js"></script>
<script src="RTCQuicTransport-helper.js"></script>
+<script src="../webrtc/dictionary-helper.js"></script>
<script>
'use strict';
@@ -21,6 +22,7 @@
// makeStandaloneQuicTransport
// makeAndStartTwoQuicTransports
// makeTwoConnectedQuicTransports
+// sleep
test(t => {
const iceTransport = makeIceTransport(t);
@@ -174,5 +176,93 @@
assert_not_equals(update_key, new Uint8Array(new_key));
}, 'Cannot mutate key retrieved from getKey().');
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ makeAndStartTwoQuicTransports(t);
+ const stats = await localQuicTransport.getStats();
+ assert_number_field(stats, 'timestamp');
+ assert_unsigned_int_field(stats, 'bytesSent');
+ assert_unsigned_int_field(stats, 'packetsSent');
+ assert_unsigned_int_field(stats, 'streamBytesSent');
+ assert_unsigned_int_field(stats, 'streamBytesReceived');
+ assert_unsigned_int_field(stats, 'numOutgoingStreamsCreated');
+ assert_unsigned_int_field(stats, 'numIncomingStreamsCreated');
+ assert_unsigned_int_field(stats, 'bytesReceived');
+ assert_unsigned_int_field(stats, 'packetsReceived');
+ assert_unsigned_int_field(stats, 'packetsProcessed');
+ assert_unsigned_int_field(stats, 'bytesRetransmitted');
+ assert_unsigned_int_field(stats, 'packetsRetransmitted');
+ assert_unsigned_int_field(stats, 'packetsLost');
+ assert_unsigned_int_field(stats, 'packetsDropped');
+ assert_unsigned_int_field(stats, 'cryptoRetransmitCount');
+ assert_unsigned_int_field(stats, 'minRttUs');
+ assert_unsigned_int_field(stats, 'smoothedRttUs');
+ assert_unsigned_int_field(stats, 'maxPacketSize');
+ assert_unsigned_int_field(stats, 'maxReceivedPacketSize');
+ assert_unsigned_int_field(stats, 'estimatedBandwidthBps');
+ assert_unsigned_int_field(stats, 'packetsReordered');
+ assert_unsigned_int_field(stats, 'blockedFramesReceived');
+ assert_unsigned_int_field(stats, 'blockedFramesSent');
+ assert_unsigned_int_field(stats, 'connectivityProbingPacketsReceived');
+}, 'Stats returned by getStats() are present.');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const localStream = localQuicTransport.createStream();
+ localStream.write({ finish: true });
+ const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
+ await remoteWatcher.wait_for('quicstream');
+ const localStats = await localQuicTransport.getStats();
+ const remoteStats = await remoteQuicTransport.getStats();
+ assert_equals(localStats.numOutgoingStreamsCreated, 1);
+ assert_equals(localStats.numIncomingStreamsCreated, 0);
+ assert_equals(remoteStats.numOutgoingStreamsCreated, 0);
+ assert_equals(remoteStats.numIncomingStreamsCreated, 1);
+}, 'getStats() returns proper stream counts after creating streams.');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ makeAndStartTwoQuicTransports(t);
+ const stats1 = await localQuicTransport.getStats();
+ await new Promise(resolve => t.step_timeout(resolve, 20));
+ const stats2 = await localQuicTransport.getStats();
+ assert_greater_than(stats2.timestamp, stats1.timestamp);
+}, 'Two separate stats returned by getStats() give different timestamps.');
+
+promise_test(async t => {
+ const quicTransport = makeStandaloneQuicTransport(t);
+ const promise = quicTransport.getStats();
+ promise_rejects(t, 'InvalidStateError', promise);
+}, 'getStats() promises immediately rejected with InvalidStateError ' +
+ `if called before 'connecting'.`);
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const promise = localQuicTransport.getStats();
+ localQuicTransport.stop();
+ promise_rejects(t, 'InvalidStateError', promise);
+}, 'getStats() promises rejected with InvalidStateError if stop() ' +
+ 'is called before being fulfilled.');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ const promise = localQuicTransport.getStats();
+ localQuicTransport.transport.stop();
+ promise_rejects(t, 'InvalidStateError', promise);
+}, 'getStats() promises rejected with InvalidStateError if ' +
+ 'RTCIceTransport calls stop() before being fulfilled.');
+
+promise_test(async t => {
+ const [ localQuicTransport, remoteQuicTransport ] =
+ await makeTwoConnectedQuicTransports(t);
+ localQuicTransport.transport.stop();
+ const promise = localQuicTransport.getStats();
+ promise_rejects(t, 'InvalidStateError', promise);
+}, 'getStats() promises immediately rejected if called after' +
+ `'closed' state.`);
+
</script>
diff --git a/webrtc-stats/idlharness.window.js b/webrtc-stats/idlharness.window.js
index 2374120..d98712f 100644
--- a/webrtc-stats/idlharness.window.js
+++ b/webrtc-stats/idlharness.window.js
@@ -7,7 +7,7 @@
idl_test(
['webrtc-stats'],
- [], // No deps
+ ['webrtc'],
idl_array => {
// No interfaces to test
}
diff --git a/webrtc/RTCPeerConnection-iceConnectionState.html b/webrtc/RTCPeerConnection-iceConnectionState.html
index 4071033..b647b3d 100644
--- a/webrtc/RTCPeerConnection-iceConnectionState.html
+++ b/webrtc/RTCPeerConnection-iceConnectionState.html
@@ -64,6 +64,12 @@
assert_equals(pc.iceConnectionState, 'new');
}, 'Initial iceConnectionState should be new');
+ test(t => {
+ const pc = new RTCPeerConnection();
+ pc.close();
+ assert_equals(pc.iceConnectionState, 'closed');
+ }, 'Closing the connection should set iceConnectionState to closed');
+
/*
4.4.4 RTCIceConnectionState Enum
checking
@@ -106,6 +112,35 @@
const pc1 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
const pc2 = new RTCPeerConnection();
+ t.add_cleanup(() => pc2.close());
+
+ let had_checking = false;
+
+ const onIceConnectionStateChange = t.step_func(() => {
+ const {iceConnectionState} = pc1;
+ if (iceConnectionState === 'checking') {
+ had_checking = true;
+ } else if (iceConnectionState === 'connected' ||
+ iceConnectionState === 'completed') {
+ assert_true(had_checking, 'state should pass checking before' +
+ ' reaching connected or completed');
+ t.done();
+ }
+ });
+
+ pc1.createDataChannel('test');
+
+ pc1.addEventListener('iceconnectionstatechange', onIceConnectionStateChange);
+
+ exchangeIceCandidates(pc1, pc2);
+ doSignalingHandshake(pc1, pc2);
+ }, 'connection with one data channel should eventually have connected or ' +
+ 'completed connection state');
+
+async_test(t => {
+ const pc1 = new RTCPeerConnection();
+ t.add_cleanup(() => pc1.close());
+ const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc2.close());
@@ -116,19 +151,22 @@
const iceTransport = pc1.sctp.transport.transport;
assert_equals(iceTransport.state, 'checking',
- 'Expect ICE transport to be in checking state when iceConnectionState is checking');
+ 'Expect ICE transport to be in checking state when' +
+ ' iceConnectionState is checking');
} else if(iceConnectionState === 'connected') {
const iceTransport = pc1.sctp.transport.transport;
assert_equals(iceTransport.state, 'connected',
- 'Expect ICE transport to be in connected state when iceConnectionState is connected');
+ 'Expect ICE transport to be in connected state when' +
+ ' iceConnectionState is connected');
} else if(iceConnectionState === 'completed') {
const iceTransport = pc1.sctp.transport.transport;
assert_equals(iceTransport.state, 'completed',
- 'Expect ICE transport to be in connected state when iceConnectionState is completed');
+ 'Expect ICE transport to be in connected state when' +
+ ' iceConnectionState is completed');
}
});
@@ -141,7 +179,8 @@
exchangeIceCandidates(pc1, pc2);
doSignalingHandshake(pc1, pc2);
- }, 'connection with one data channel should eventually have connected connection state');
+ }, 'connection with one data channel should eventually ' +
+ 'have connected connection state');
/*
TODO
diff --git a/webusb/usb-supported-by-feature-policy.html b/webusb/usb-supported-by-feature-policy.html
new file mode 100644
index 0000000..d5b585a
--- /dev/null
+++ b/webusb/usb-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that usb is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://wicg.github.io/webusb/#feature-policy">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('usb', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise usb.');
+</script>
diff --git a/webvr/webvr-supported-by-feature-policy.html b/webvr/webvr-supported-by-feature-policy.html
new file mode 100644
index 0000000..9487c35
--- /dev/null
+++ b/webvr/webvr-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that xr is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://immersive-web.github.io/webxr/#feature-policy">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('xr', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise xr.');
+</script>
diff --git a/xhr/sync-xhr-supported-by-feature-policy.html b/xhr/sync-xhr-supported-by-feature-policy.html
new file mode 100644
index 0000000..45588bf
--- /dev/null
+++ b/xhr/sync-xhr-supported-by-feature-policy.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Test that sync-xhr is advertised in the feature list</title>
+<link rel="help" href="https://w3c.github.io/webappsec-feature-policy/#dom-featurepolicy-features">
+<link rel="help" href="https://xhr.spec.whatwg.org/#feature-policy-integration">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ assert_in_array('sync-xhr', document.featurePolicy.features());
+}, 'document.featurePolicy.features should advertise sync-xhr.');
+</script>