Note: This is a manual test because it writes/reads to the shared system
diff --git a/tests/wpt/web-platform-tests/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html b/tests/wpt/web-platform-tests/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html
index bc8511efa72..fded721f9bf 100644
--- a/tests/wpt/web-platform-tests/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html
+++ b/tests/wpt/web-platform-tests/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html
@@ -10,19 +10,19 @@ async function readWriteTest(textInput) {
promise_test(async t => {
const blobInput = new Blob([textInput], {type: 'text/plain'});
- await navigator.clipboard.write([blobInput]);
+ await navigator.clipboard.write({'text/plain': blobInput});
const blobsOutput = await navigator.clipboard.read();
- assert_equals(blobsOutput.length, 1);
- const blobOutput = blobsOutput[0];
- assert_equals(blobOutput.type, "text/plain");
+ assert_equals(Object.keys(blobsOutput).length, 1);
+ const blobOutput = blobsOutput['text/plain'];
+ assert_equals(blobOutput.type, 'text/plain');
const textOutput = await (new Response(blobOutput)).text();
assert_equals(textOutput, textInput);
- }, "Verify write and read clipboard given text: " + textInput);
+ }, 'Verify write and read clipboard given text: ' + textInput);
}
-readWriteTest("Clipboard write ([text/plain Blob]) -> read ([text/plain Blob]) test");
-readWriteTest("non-Latin1 text encoding test データ");
+readWriteTest('Clipboard write ([text/plain Blob]) -> read ([text/plain Blob]) test');
+readWriteTest('non-Latin1 text encoding test データ');
Note: This is a manual test because it writes/reads to the shared system
diff --git a/tests/wpt/web-platform-tests/clipboard-apis/async-write-blobtext-read-text-manual.https.html b/tests/wpt/web-platform-tests/clipboard-apis/async-write-blobtext-read-text-manual.https.html
index b1b85de65e8..98ff7c27b66 100644
--- a/tests/wpt/web-platform-tests/clipboard-apis/async-write-blobtext-read-text-manual.https.html
+++ b/tests/wpt/web-platform-tests/clipboard-apis/async-write-blobtext-read-text-manual.https.html
@@ -8,15 +8,15 @@ async function readWriteTest(textInput) {
promise_test(async t => {
const blobInput = new Blob([textInput], {type: 'text/plain'});
- await navigator.clipboard.write([blobInput]);
+ await navigator.clipboard.write({'text/plain': blobInput});
const textOutput = await navigator.clipboard.readText();
assert_equals(textOutput, textInput);
- }, "Verify write and read clipboard given text: " + textInput);
+ }, 'Verify write and read clipboard given text: ' + textInput);
}
-readWriteTest("Clipboard write ([text/plain Blob]) -> read text test");
-readWriteTest("non-Latin1 text encoding test データ");
+readWriteTest('Clipboard write ([text/plain Blob]) -> read text test');
+readWriteTest('non-Latin1 text encoding test データ');
Note: This is a manual test because it writes/reads to the shared system
diff --git a/tests/wpt/web-platform-tests/clipboard-apis/async-write-duplicate-mime-type-manual.https.html b/tests/wpt/web-platform-tests/clipboard-apis/async-write-duplicate-mime-type-manual.https.html
deleted file mode 100644
index 8e249fc993a..00000000000
--- a/tests/wpt/web-platform-tests/clipboard-apis/async-write-duplicate-mime-type-manual.https.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
- Async Clipboard write duplicate mime type test
-
-
-
-
-
-
- Note: This is a manual test because it writes/reads to the shared system
- clipboard and thus cannot be run async with other tests that might interact
- with the clipboard.
-
The bottom image should display the same image as the top image.
Original Image:
-
Image after copy/paste:
-
-
+
+
Note: This is a manual test because it writes/reads to the shared system
diff --git a/tests/wpt/web-platform-tests/clipboard-apis/async-write-text-read-blobtext-manual.https.html b/tests/wpt/web-platform-tests/clipboard-apis/async-write-text-read-blobtext-manual.https.html
index b54fa609b65..ab85a6fc649 100644
--- a/tests/wpt/web-platform-tests/clipboard-apis/async-write-text-read-blobtext-manual.https.html
+++ b/tests/wpt/web-platform-tests/clipboard-apis/async-write-text-read-blobtext-manual.https.html
@@ -8,17 +8,17 @@ async function readWriteTest(textInput) {
promise_test(async t => {
await navigator.clipboard.writeText(textInput);
const blobsOutput = await navigator.clipboard.read();
- assert_equals(blobsOutput.length, 1);
- const blobOutput = blobsOutput[0];
- assert_equals(blobOutput.type, "text/plain");
+ assert_equals(Object.keys(blobsOutput).length, 1);
+ const blobOutput = blobsOutput['text/plain'];
+ assert_equals(blobOutput.type, 'text/plain');
const textOutput = await (new Response(blobOutput)).text();
assert_equals(textOutput, textInput);
- }, "Verify write and read clipboard given text: " + textInput);
+ }, 'Verify write and read clipboard given text: ' + textInput);
}
-readWriteTest("Clipboard write text -> read ([text/plain Blob]) test");
-readWriteTest("non-Latin1 text encoding test データ");
+readWriteTest('Clipboard write text -> read ([text/plain Blob]) test');
+readWriteTest('non-Latin1 text encoding test データ');
Note: This is a manual test because it writes/reads to the shared system
diff --git a/tests/wpt/web-platform-tests/clipboard-apis/async-write-text-read-text-manual.https.html b/tests/wpt/web-platform-tests/clipboard-apis/async-write-text-read-text-manual.https.html
index 496bdd78c7a..25c7edb43f0 100644
--- a/tests/wpt/web-platform-tests/clipboard-apis/async-write-text-read-text-manual.https.html
+++ b/tests/wpt/web-platform-tests/clipboard-apis/async-write-text-read-text-manual.https.html
@@ -10,11 +10,11 @@ async function readWriteTest(textInput) {
const textOutput = await navigator.clipboard.readText();
assert_equals(textOutput, textInput);
- }, "Verify write and read clipboard given text: " + textInput);
+ }, 'Verify write and read clipboard given text: ' + textInput);
}
-readWriteTest("Clipboard write text -> read text test");
-readWriteTest("non-Latin1 text encoding test データ");
+readWriteTest('Clipboard write text -> read text test');
+readWriteTest('non-Latin1 text encoding test データ');
Note: This is a manual test because it writes/reads to the shared system
diff --git a/tests/wpt/web-platform-tests/clipboard-apis/copy-event-manual.html b/tests/wpt/web-platform-tests/clipboard-apis/copy-event-manual.html
index e4cf3379ace..6f687af196f 100644
--- a/tests/wpt/web-platform-tests/clipboard-apis/copy-event-manual.html
+++ b/tests/wpt/web-platform-tests/clipboard-apis/copy-event-manual.html
@@ -11,9 +11,9 @@ async_test(t => {
document.oncopy = t.step_func_done(event => {
// Nothing can be asserted about the event target until
// https://github.com/w3c/clipboard-apis/issues/70 is resolved.
- // assert_equals(event.target, document.body, "event.target");
- assert_true(event.isTrusted, "event.isTrusted");
- assert_true(event.composed, "event.composed");
+ // assert_equals(event.target, document.body, 'event.target');
+ assert_true(event.isTrusted, 'event.isTrusted');
+ assert_true(event.composed, 'event.composed');
});
});
diff --git a/tests/wpt/web-platform-tests/clipboard-apis/cut-event-manual.html b/tests/wpt/web-platform-tests/clipboard-apis/cut-event-manual.html
index abef6f94bf6..c5593171754 100644
--- a/tests/wpt/web-platform-tests/clipboard-apis/cut-event-manual.html
+++ b/tests/wpt/web-platform-tests/clipboard-apis/cut-event-manual.html
@@ -11,9 +11,9 @@ async_test(t => {
document.oncut = t.step_func_done(event => {
// Nothing can be asserted about the event target until
// https://github.com/w3c/clipboard-apis/issues/70 is resolved.
- // assert_equals(event.target, document.body, "event.target");
- assert_true(event.isTrusted, "event.isTrusted");
- assert_true(event.composed, "event.composed");
+ // assert_equals(event.target, document.body, 'event.target');
+ assert_true(event.isTrusted, 'event.isTrusted');
+ assert_true(event.composed, 'event.composed');
});
});
diff --git a/tests/wpt/web-platform-tests/clipboard-apis/paste-event-manual.html b/tests/wpt/web-platform-tests/clipboard-apis/paste-event-manual.html
index 4131a41bff6..19e6b95c5f3 100644
--- a/tests/wpt/web-platform-tests/clipboard-apis/paste-event-manual.html
+++ b/tests/wpt/web-platform-tests/clipboard-apis/paste-event-manual.html
@@ -9,13 +9,13 @@
diff --git a/tests/wpt/web-platform-tests/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html b/tests/wpt/web-platform-tests/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html
deleted file mode 100644
index 8310e66cc4a..00000000000
--- a/tests/wpt/web-platform-tests/css/css-flexbox/intrinsic-width-overflow-auto.tentative.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the left,
+ and a trailing space of 200px, which is as wide as the black block to the right.
+
+
+
+
The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the left,
+ and a trailing space of 150px, which is as wide as the black block to the right.
+
+
+
+
The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the left,
+ and a trailing space of 100px, which is as wide as the black block to the right.
+
+
+
+
RTL case
+
+
The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the right,
+ and a trailing space of 200px, which is as wide as the black block to the left.
+
+
+
+
The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the right,
+ and a trailing space of 150px, which is as wide as the black block to the left.
+
+
+
+
The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the right,
+ and a trailing space of 100px, which is as wide as the black block to the left.
The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the left,
+ and a trailing space of 200px, which is as wide as the black block to the right.
+
+
+
+ →
+
+
+
+
The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the left,
+ and a trailing space of 150px, which is as wide as the black block to the right.
+
+
+
+
The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the left,
+ and a trailing space of 100px, which is as wide as the black block to the right.
+
+
+
+
RTL case
+
+
The test passes if the arrow has a leading space of 100px, which is as wide as the black block to the right,
+ and a trailing space of 200px, which is as wide as the black block to the left.
+
+
+
+
The test passes if the arrow has a leading space of 150px, which is as wide as the black block to the right,
+ and a trailing space of 150px, which is as wide as the black block to the left.
+
+
+
+
The test passes if the arrow has a leading space of 200px, which is as wide as the black block to the right,
+ and a trailing space of 100px, which is as wide as the black block to the left.
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/media-source/mediasource-correct-frames-after-reappend.html b/tests/wpt/web-platform-tests/media-source/mediasource-correct-frames-after-reappend.html
new file mode 100644
index 00000000000..5c0f2e11195
--- /dev/null
+++ b/tests/wpt/web-platform-tests/media-source/mediasource-correct-frames-after-reappend.html
@@ -0,0 +1,162 @@
+
+
+
+
+ Frame checking test for MSE playback in presence of a reappend.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/media-source/mediasource-correct-frames.html b/tests/wpt/web-platform-tests/media-source/mediasource-correct-frames.html
new file mode 100644
index 00000000000..4ef3f4605e6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/media-source/mediasource-correct-frames.html
@@ -0,0 +1,146 @@
+
+
+
+
+ Frame checking test for simple MSE playback.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/media-source/mp4/test-boxes-audio.mp4 b/tests/wpt/web-platform-tests/media-source/mp4/test-boxes-audio.mp4
new file mode 100644
index 00000000000..b1cabbfd21e
Binary files /dev/null and b/tests/wpt/web-platform-tests/media-source/mp4/test-boxes-audio.mp4 differ
diff --git a/tests/wpt/web-platform-tests/media-source/mp4/test-boxes-video.mp4 b/tests/wpt/web-platform-tests/media-source/mp4/test-boxes-video.mp4
new file mode 100644
index 00000000000..714c17ca126
Binary files /dev/null and b/tests/wpt/web-platform-tests/media-source/mp4/test-boxes-video.mp4 differ
diff --git a/tests/wpt/web-platform-tests/mediacapture-depth/dictionary-manual.https.html b/tests/wpt/web-platform-tests/mediacapture-depth/dictionary-manual.https.html
index e464f293fb1..0a5b8248815 100644
--- a/tests/wpt/web-platform-tests/mediacapture-depth/dictionary-manual.https.html
+++ b/tests/wpt/web-platform-tests/mediacapture-depth/dictionary-manual.https.html
@@ -24,220 +24,28 @@
let advanced_constraints_depth = [{
videoKind: "depth",
- focalLengthX: 0.5,
- focalLengthY: 0.5,
- principalPointX: 0.1,
- principalPointY: 0.1,
- deprojectionDistortionCoefficients: true,
- projectionDistortionCoefficients: true,
- depthNear: 0.5,
- depthFar: 1,
- depthToVideoTransform: true
}];
let advanced_constraints_color = [{
videoKind: "color",
- focalLengthX: 0.5,
- focalLengthY: 0.5,
- principalPointX: 0.1,
- principalPointY: 0.1,
- deprojectionDistortionCoefficients: true,
- projectionDistortionCoefficients: true
-}];
-
-/*
- partial dictionary MediaTrackCapabilities {
- // Apply to both depth stream track and color stream track:
- DOMString videoKind;
- (double or DoubleRange) focalLengthX;
- (double or DoubleRange) focalLengthY;
- (double or DoubleRange) principalPointX;
- (double or DoubleRange) principalPointY;
- boolean deprojectionDistortionCoefficients;
- boolean projectionDistortionCoefficients;
- // Apply to depth stream track:
- (double or DoubleRange) depthNear;
- (double or DoubleRange) depthFar;
- boolean depthToVideoTransform;
- };
-
- dictionary DoubleRange {
- double max;
- double min;
- };
-*/
+ }];
function validateMediaTrackCapabilities(capabilities, type) {
assert_string_field(capabilities, 'videoKind');
- assert_number_or_number_range_field(capabilities, 'focalLengthX');
- assert_number_or_number_range_field(capabilities, 'focalLengthY');
- assert_number_or_number_range_field(capabilities, 'principalPointX');
- assert_number_or_number_range_field(capabilities, 'principalPointY');
- assert_boolean_field(capabilities, 'deprojectionDistortionCoefficients');
- assert_boolean_field(capabilities, 'projectionDistortionCoefficients');
- if (type == "depth") {
- assert_number_or_number_range_field(capabilities, 'depthNear');
- assert_number_or_number_range_field(capabilities, 'depthFar');
- assert_boolean_field(capabilities, 'depthToVideoTransform');
- }
}
-/*
- partial dictionary MediaTrackConstraintSet {
- // Apply to both depth stream track and color stream track:
- ConstrainDOMString videoKind;
- ConstrainDouble focalLengthX;
- ConstrainDouble focalLengthY;
- ConstrainDouble principalPointX;
- ConstrainDouble principalPointY;
- ConstrainBoolean deprojectionDistortionCoefficients;
- ConstrainBoolean projectionDistortionCoefficients;
- // Apply to depth stream track:
- ConstrainDouble depthNear;
- ConstrainDouble depthFar;
- ConstrainBoolean depthToVideoTransform;
- };
-
- typedef (DOMString or sequence or ConstrainDOMStringParameters) ConstrainDOMString;
-
- dictionary ConstrainDOMStringParameters {
- (DOMString or sequence) exact;
- (DOMString or sequence) ideal;
- };
-
- typedef (double or ConstrainDoubleRange) ConstrainDouble;
-
- dictionary DoubleRange {
- double max;
- double min;
- };
-
- dictionary ConstrainDoubleRange : DoubleRange {
- double exact;
- double ideal;
- };
-
- typedef (boolean or ConstrainBooleanParameters) ConstrainBoolean;
-
- dictionary ConstrainBooleanParameters {
- boolean exact;
- boolean ideal;
- };
-*/
function validateMediaTrackConstraintSet(constraints, type) {
assert_constrain_string_field(constraints, 'videoKind');
- assert_constrain_number_field(constraints, 'focalLengthX');
- assert_constrain_number_field(constraints, 'focalLengthY');
- assert_constrain_number_field(constraints, 'principalPointX');
- assert_constrain_number_field(constraints, 'principalPointY');
- assert_constrain_boolean_field(constraints, 'deprojectionDistortionCoefficients');
- assert_constrain_boolean_field(constraints, 'projectionDistortionCoefficients');
- if (type == "depth") {
- assert_constrain_number_field(constraints, 'depthNear');
- assert_constrain_number_field(constraints, 'depthFar');
- assert_constrain_boolean_field(constraints, 'depthToVideoTransform');
- }
-}
-
-/*
- partial dictionary MediaTrackSettings {
- // Apply to both depth stream track and color stream track:
- DOMString videoKind;
- double focalLengthX;
- double focalLengthY;
- double principalPointX;
- double principalPointY;
- DistortionCoefficients deprojectionDistortionCoefficients;
- DistortionCoefficients projectionDistortionCoefficients;
- // Apply to depth stream track:
- double depthNear;
- double depthFar;
- Transformation depthToVideoTransform;
- };
-
- dictionary DistortionCoefficients {
- double k1;
- double k2;
- double p1;
- double p2;
- double k3;
- };
-
- dictionary Transformation {
- Float32Array transformationMatrix;
- DOMString videoDeviceId;
- };
-
- enum VideoKindEnum {
- "color",
- "depth"
- };
-*/
-
-function validateDistortionCoefficients(coefficients) {
- assert_number_field(coefficients, 'k1');
- assert_number_field(coefficients, 'k2');
- assert_number_field(coefficients, 'p1');
- assert_number_field(coefficients, 'p2');
- assert_number_field(coefficients, 'k3');
-}
-
-function validateTransformation(depthToVideoTransform) {
- assert_array_field(depthToVideoTransform, 'transformationMatrix');
- assert_string_field(depthToVideoTransform, 'videoDeviceId');
}
function validateMediaTrackSettings(settings, type) {
assert_string_field(settings, 'videoKind');
assert_enum_field(settings, 'videoKind', ['color', 'depth'])
- assert_number_field(settings, 'focalLengthX');
- assert_number_field(settings, 'focalLengthY');
- assert_number_field(settings, 'principalPointX');
- assert_number_field(settings, 'principalPointY');
- if (settings.deprojectionDistortionCoefficients) {
- validateDistortionCoefficients(settings.deprojectionDistortionCoefficients);
- }
- if (settings.projectionDistortionCoefficients) {
- validateDistortionCoefficients(settings.projectionDistortionCoefficients);
- }
- if (type == "depth") {
- assert_number_field(settings, 'depthNear');
- assert_number_field(settings, 'depthFar');
- if (settings.depthToVideoTransform) {
- validateTransformation(settings.depthToVideoTransform);
- }
- }
}
-/*
- partial dictionary MediaTrackSupportedConstraints {
- // Apply to both depth stream track and color stream track:
- boolean videoKind = true;
- boolean focalLengthX = false;
- boolean focalLengthY = false;
- boolean principalPointX = false;
- boolean principalPointY = false;
- boolean deprojectionDistortionCoefficients = false;
- boolean projectionDistortionCoefficients = false;
- // Apply to depth stream track:
- boolean depthNear = false;
- boolean depthFar = false;
- boolean depthToVideoTransform = false;
- };
-*/
-
function validateMediaTrackSupportedConstraints(supports) {
assert_boolean_field(supports, 'videoKind', true);
- assert_boolean_field(supports, 'focalLengthX', false);
- assert_boolean_field(supports, 'focalLengthY', false);
- assert_boolean_field(supports, 'principalPointX', false);
- assert_boolean_field(supports, 'principalPointY', false);
- assert_boolean_field(supports, 'deprojectionDistortionCoefficients', false);
- assert_boolean_field(supports, 'projectionDistortionCoefficients', false);
- assert_boolean_field(supports, 'depthNear', false);
- assert_boolean_field(supports, 'depthFar', false);
- assert_boolean_field(supports, 'depthToVideoTransform', false);
}
function runDictionaryTests(type, constraints) {
diff --git a/tests/wpt/web-platform-tests/orientation-event/free-fall-manual.html b/tests/wpt/web-platform-tests/orientation-event/free-fall-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/free-fall-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/free-fall-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/horizontal-surface-manual.html b/tests/wpt/web-platform-tests/orientation-event/horizontal-surface-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/horizontal-surface-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/horizontal-surface-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/screen-upmost-manual.html b/tests/wpt/web-platform-tests/orientation-event/screen-upmost-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/screen-upmost-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/screen-upmost-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/screen-upright-manual.html b/tests/wpt/web-platform-tests/orientation-event/screen-upright-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/screen-upright-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/screen-upright-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t001-manual.html b/tests/wpt/web-platform-tests/orientation-event/t001-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t001-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t001-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t002-manual.html b/tests/wpt/web-platform-tests/orientation-event/t002-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t002-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t002-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t003-manual.html b/tests/wpt/web-platform-tests/orientation-event/t003-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t003-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t003-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t006-manual.html b/tests/wpt/web-platform-tests/orientation-event/t006-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t006-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t006-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t009-manual.html b/tests/wpt/web-platform-tests/orientation-event/t009-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t009-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t009-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t010-manual.html b/tests/wpt/web-platform-tests/orientation-event/t010-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t010-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t010-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t012-manual.html b/tests/wpt/web-platform-tests/orientation-event/t012-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t012-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t012-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t021-manual.html b/tests/wpt/web-platform-tests/orientation-event/t021-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t021-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t021-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t022-manual.html b/tests/wpt/web-platform-tests/orientation-event/t022-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t022-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t022-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t023-manual.html b/tests/wpt/web-platform-tests/orientation-event/t023-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t023-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t023-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t025-manual.html b/tests/wpt/web-platform-tests/orientation-event/t025-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t025-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t025-manual.https.html
diff --git a/tests/wpt/web-platform-tests/orientation-event/t028-manual.html b/tests/wpt/web-platform-tests/orientation-event/t028-manual.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/orientation-event/t028-manual.html
rename to tests/wpt/web-platform-tests/orientation-event/t028-manual.https.html
diff --git a/tests/wpt/web-platform-tests/payment-method-basic-card/META.yml b/tests/wpt/web-platform-tests/payment-method-basic-card/META.yml
index b1d851431cb..30994b67caf 100644
--- a/tests/wpt/web-platform-tests/payment-method-basic-card/META.yml
+++ b/tests/wpt/web-platform-tests/payment-method-basic-card/META.yml
@@ -1,5 +1,5 @@
spec: https://w3c.github.io/payment-method-basic-card/
suggested_reviewers:
- - mnoorenberghe
+ - danyao
- marcoscaceres
- rsolomakhin
diff --git a/tests/wpt/web-platform-tests/payment-method-basic-card/apply_the_modifiers.html b/tests/wpt/web-platform-tests/payment-method-basic-card/apply_the_modifiers.html
new file mode 100644
index 00000000000..8b9fe78e2e4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/payment-method-basic-card/apply_the_modifiers.html
@@ -0,0 +1,152 @@
+
+
+
+ Payment Method Basic Card: apply the modifiers
+
+
+
+
+
+
Manual tests
+
+ Note: this test requires that there is at at least one
+ registered "visa" card. If the payment-sheet total's
+ label displays "PASS", and the value US$12345, then a test has passed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/payment-method-basic-card/steps_for_selecting_the_payment_handler.html b/tests/wpt/web-platform-tests/payment-method-basic-card/steps_for_selecting_the_payment_handler.html
new file mode 100644
index 00000000000..19cefadb3d4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/payment-method-basic-card/steps_for_selecting_the_payment_handler.html
@@ -0,0 +1,100 @@
+
+
+
+ Payment Method Basic Card: steps for selecting the payment handler
+
+
+
+
+
+
Manual tests
+
+ When each button is clicked, the
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/payment-request/META.yml b/tests/wpt/web-platform-tests/payment-request/META.yml
index 558db3e088c..5897c26fe88 100644
--- a/tests/wpt/web-platform-tests/payment-request/META.yml
+++ b/tests/wpt/web-platform-tests/payment-request/META.yml
@@ -2,7 +2,6 @@ spec: https://w3c.github.io/payment-request/
suggested_reviewers:
- marcoscaceres
- rsolomakhin
- - domenic
- zouhir
- romandev
- edenchuang
diff --git a/tests/wpt/web-platform-tests/payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html b/tests/wpt/web-platform-tests/payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html
index abbf39ba395..99b7a28e90d 100644
--- a/tests/wpt/web-platform-tests/payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html
+++ b/tests/wpt/web-platform-tests/payment-request/PaymentRequestUpdateEvent/updateWith-method-abort-update-manual.https.html
@@ -220,7 +220,7 @@ function testBadUpdate(button, badDetails, expectedError, errorCode) {
const badDetails = Object.assign({}, validDetails, { displayItems: invalidPaymentItems });
testBadUpdate(this, badDetails, new RangeError());
">
- Updating with a displayItem with an invalid currency results in TypeError.
+ Updating with a displayItem with an invalid currency results in RangeError.
diff --git a/tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method-manual.https.html b/tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method-manual.tentative.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method-manual.https.html
rename to tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method-manual.tentative.https.html
diff --git a/tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method-protection.https.html b/tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method-protection.https.html
rename to tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https.html
diff --git a/tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method.https.html b/tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html
similarity index 100%
rename from tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method.https.html
rename to tests/wpt/web-platform-tests/payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html
diff --git a/tests/wpt/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html b/tests/wpt/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html
index 8bab88212ba..6cddeb97365 100644
--- a/tests/wpt/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html
+++ b/tests/wpt/web-platform-tests/payment-request/updateWith-method-pmi-handling-manual.https.html
@@ -1,5 +1,4 @@
-
Test for validity of payment method identifiers when calling updateWith() method
@@ -7,7 +6,11 @@
+
+
+
+
+
+
+
Pointer Events movement in locked state test
+
+
+ Test Description: This test checks the pointer event coordinates stays unchanged when pointer is locked.
+
+
Press left button down on the green rectangle and hold it.
+
Move the mouse inside the green rectangle.
+
Release mouse button.
+
+
+
+ Test passes if the proper behavior of the events is observed.
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/portals/portal-activate-data.html b/tests/wpt/web-platform-tests/portals/portal-activate-data.html
index e2417cb7332..0d8ec33cae7 100644
--- a/tests/wpt/web-platform-tests/portals/portal-activate-data.html
+++ b/tests/wpt/web-platform-tests/portals/portal-activate-data.html
@@ -2,6 +2,8 @@
Tests passing of data along with portal activation
+
+
+
diff --git a/tests/wpt/web-platform-tests/resize-observer/idlharness.window.js b/tests/wpt/web-platform-tests/resize-observer/idlharness.window.js
index 592af2e0c07..2d459b0b126 100644
--- a/tests/wpt/web-platform-tests/resize-observer/idlharness.window.js
+++ b/tests/wpt/web-platform-tests/resize-observer/idlharness.window.js
@@ -7,7 +7,7 @@
// https://wicg.github.io/ResizeObserver/
idl_test(
- ['ResizeObserver'],
+ ['resize-observer'],
['dom', 'geometry'],
async idl_array => {
idl_array.add_objects({
diff --git a/tests/wpt/web-platform-tests/resources/chromium/mock-barcodedetection.js b/tests/wpt/web-platform-tests/resources/chromium/mock-barcodedetection.js
new file mode 100644
index 00000000000..2558bbda589
--- /dev/null
+++ b/tests/wpt/web-platform-tests/resources/chromium/mock-barcodedetection.js
@@ -0,0 +1,124 @@
+"use strict";
+
+var BarcodeDetectionTest = (() => {
+ // Class that mocks BarcodeDetectionProvider interface defined in
+ // https://cs.chromium.org/chromium/src/services/shape_detection/public/mojom/barcodedetection_provider.mojom
+ class MockBarcodeDetectionProvider {
+ constructor() {
+ this.bindingSet_ = new mojo.BindingSet(
+ shapeDetection.mojom.BarcodeDetectionProvider);
+
+ this.interceptor_ = new MojoInterfaceInterceptor(
+ shapeDetection.mojom.BarcodeDetectionProvider.name);
+ this.interceptor_.oninterfacerequest =
+ e => this.bindingSet_.addBinding(this, e.handle);
+ this.interceptor_.start();
+ }
+
+ createBarcodeDetection(request, options) {
+ this.mockService_ = new MockBarcodeDetection(request, options);
+ }
+
+ enumerateSupportedFormats() {
+ return Promise.resolve({
+ supportedFormats: [
+ shapeDetection.mojom.BarcodeFormat.AZTEC,
+ shapeDetection.mojom.BarcodeFormat.DATA_MATRIX,
+ shapeDetection.mojom.BarcodeFormat.QR_CODE,
+ ]
+ });
+ }
+
+ getFrameData() {
+ return this.mockService_.bufferData_;
+ }
+
+ getFormats() {
+ return this.mockService_.options_.formats;
+ }
+
+ reset() {
+ this.mockService_ = null;
+ this.bindingSet_.closeAllBindings();
+ this.interceptor_.stop();
+ }
+ }
+
+ // Class that mocks BarcodeDetection interface defined in
+ // https://cs.chromium.org/chromium/src/services/shape_detection/public/mojom/barcodedetection.mojom
+ class MockBarcodeDetection {
+ constructor(request, options) {
+ this.options_ = options;
+ this.binding_ =
+ new mojo.Binding(shapeDetection.mojom.BarcodeDetection,
+ this, request);
+ }
+
+ detect(bitmapData) {
+ this.bufferData_ =
+ new Uint32Array(getArrayBufferFromBigBuffer(bitmapData.pixelData));
+ return Promise.resolve({
+ results: [
+ {
+ rawValue : "cats",
+ boundingBox: { x: 1.0, y: 1.0, width: 100.0, height: 100.0 },
+ format: shapeDetection.mojom.BarcodeFormat.QR_CODE,
+ cornerPoints: [
+ { x: 1.0, y: 1.0 },
+ { x: 101.0, y: 1.0 },
+ { x: 101.0, y: 101.0 },
+ { x: 1.0, y: 101.0 }
+ ],
+ },
+ {
+ rawValue : "dogs",
+ boundingBox: { x: 2.0, y: 2.0, width: 50.0, height: 50.0 },
+ format: shapeDetection.mojom.BarcodeFormat.CODE_128,
+ cornerPoints: [
+ { x: 2.0, y: 2.0 },
+ { x: 52.0, y: 2.0 },
+ { x: 52.0, y: 52.0 },
+ { x: 2.0, y: 52.0 }
+ ],
+ },
+ ],
+ });
+ }
+ }
+
+ let testInternal = {
+ initialized: false,
+ MockBarcodeDetectionProvider: null
+ }
+
+ class BarcodeDetectionTestChromium {
+ constructor() {
+ Object.freeze(this); // Make it immutable.
+ }
+
+ initialize() {
+ if (testInternal.initialized)
+ throw new Error('Call reset() before initialize().');
+
+ testInternal.MockBarcodeDetectionProvider = new MockBarcodeDetectionProvider;
+ testInternal.initialized = true;
+ }
+
+ // Resets state of barcode detection mocks between test runs.
+ async reset() {
+ if (!testInternal.initialized)
+ throw new Error('Call initialize() before reset().');
+ testInternal.MockBarcodeDetectionProvider.reset();
+ testInternal.MockBarcodeDetectionProvider = null;
+ testInternal.initialized = false;
+
+ await new Promise(resolve => setTimeout(resolve, 0));
+ }
+
+ MockBarcodeDetectionProvider() {
+ return testInternal.MockBarcodeDetectionProvider;
+ }
+ }
+
+ return BarcodeDetectionTestChromium;
+})();
diff --git a/tests/wpt/web-platform-tests/resources/chromium/mock-barcodedetection.js.headers b/tests/wpt/web-platform-tests/resources/chromium/mock-barcodedetection.js.headers
new file mode 100644
index 00000000000..6c61a34a4ec
--- /dev/null
+++ b/tests/wpt/web-platform-tests/resources/chromium/mock-barcodedetection.js.headers
@@ -0,0 +1 @@
+Content-Type: text/javascript; charset=utf-8
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/resources/chromium/mock-facedetection.js b/tests/wpt/web-platform-tests/resources/chromium/mock-facedetection.js
new file mode 100644
index 00000000000..1275e4dd2f5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/resources/chromium/mock-facedetection.js
@@ -0,0 +1,131 @@
+"use strict";
+
+var FaceDetectionTest = (() => {
+ // Class that mocks FaceDetectionProvider interface defined in
+ // https://cs.chromium.org/chromium/src/services/shape_detection/public/mojom/facedetection_provider.mojom
+ class MockFaceDetectionProvider {
+ constructor() {
+ this.bindingSet_ = new mojo.BindingSet(
+ shapeDetection.mojom.FaceDetectionProvider);
+
+ this.interceptor_ = new MojoInterfaceInterceptor(
+ shapeDetection.mojom.FaceDetectionProvider.name);
+ this.interceptor_.oninterfacerequest =
+ e => this.bindingSet_.addBinding(this, e.handle);
+ this.interceptor_.start();
+ }
+
+ createFaceDetection(request, options) {
+ this.mockService_ = new MockFaceDetection(request, options);
+ }
+
+ getFrameData() {
+ return this.mockService_.bufferData_;
+ }
+
+ getMaxDetectedFaces() {
+ return this.mockService_.maxDetectedFaces_;
+ }
+
+ getFastMode () {
+ return this.mockService_.fastMode_;
+ }
+
+ reset() {
+ this.mockService_ = null;
+ this.bindingSet_.closeAllBindings();
+ this.interceptor_.stop();
+ }
+ }
+
+ // Class that mocks FaceDetection interface defined in
+ // https://cs.chromium.org/chromium/src/services/shape_detection/public/mojom/facedetection.mojom
+ class MockFaceDetection {
+ constructor(request, options) {
+ this.maxDetectedFaces_ = options.maxDetectedFaces;
+ this.fastMode_ = options.fastMode;
+ this.binding_ =
+ new mojo.Binding(shapeDetection.mojom.FaceDetection,
+ this, request);
+ }
+
+ detect(bitmapData) {
+ this.bufferData_ =
+ new Uint32Array(getArrayBufferFromBigBuffer(bitmapData.pixelData));
+ return Promise.resolve({
+ results: [
+ {
+ boundingBox: {x: 1.0, y: 1.0, width: 100.0, height: 100.0},
+ landmarks: [{
+ type: shapeDetection.mojom.LandmarkType.EYE,
+ locations: [{x: 4.0, y: 5.0}]
+ },
+ {
+ type: shapeDetection.mojom.LandmarkType.EYE,
+ locations: [
+ {x: 4.0, y: 5.0}, {x: 5.0, y: 4.0}, {x: 6.0, y: 3.0},
+ {x: 7.0, y: 4.0}, {x: 8.0, y: 5.0}, {x: 7.0, y: 6.0},
+ {x: 6.0, y: 7.0}, {x: 5.0, y: 6.0}
+ ]
+ }]
+ },
+ {
+ boundingBox: {x: 2.0, y: 2.0, width: 200.0, height: 200.0},
+ landmarks: [{
+ type: shapeDetection.mojom.LandmarkType.NOSE,
+ locations: [{x: 100.0, y: 50.0}]
+ },
+ {
+ type: shapeDetection.mojom.LandmarkType.NOSE,
+ locations: [
+ {x: 80.0, y: 50.0}, {x: 70.0, y: 60.0}, {x: 60.0, y: 70.0},
+ {x: 70.0, y: 60.0}, {x: 80.0, y: 70.0}, {x: 90.0, y: 80.0},
+ {x: 100.0, y: 70.0}, {x: 90.0, y: 60.0}, {x: 80.0, y: 50.0}
+ ]
+ }]
+ },
+ {
+ boundingBox: {x: 3.0, y: 3.0, width: 300.0, height: 300.0},
+ landmarks: []
+ },
+ ]
+ });
+ }
+ }
+
+ let testInternal = {
+ initialized: false,
+ MockFaceDetectionProvider: null
+ }
+
+ class FaceDetectionTestChromium {
+ constructor() {
+ Object.freeze(this); // Make it immutable.
+ }
+
+ initialize() {
+ if (testInternal.initialized)
+ throw new Error('Call reset() before initialize().');
+
+ testInternal.MockFaceDetectionProvider = new MockFaceDetectionProvider;
+ testInternal.initialized = true;
+ }
+
+ // Resets state of face detection mocks between test runs.
+ async reset() {
+ if (!testInternal.initialized)
+ throw new Error('Call initialize() before reset().');
+ testInternal.MockFaceDetectionProvider.reset();
+ testInternal.MockFaceDetectionProvider = null;
+ testInternal.initialized = false;
+
+ await new Promise(resolve => setTimeout(resolve, 0));
+ }
+
+ MockFaceDetectionProvider() {
+ return testInternal.MockFaceDetectionProvider;
+ }
+ }
+
+ return FaceDetectionTestChromium;
+})();
diff --git a/tests/wpt/web-platform-tests/resources/chromium/mock-facedetection.js.headers b/tests/wpt/web-platform-tests/resources/chromium/mock-facedetection.js.headers
new file mode 100644
index 00000000000..6c61a34a4ec
--- /dev/null
+++ b/tests/wpt/web-platform-tests/resources/chromium/mock-facedetection.js.headers
@@ -0,0 +1 @@
+Content-Type: text/javascript; charset=utf-8
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html
index cb4ed30a37f..04e98266b4f 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html
@@ -1,4 +1,5 @@
+
@@ -56,21 +57,25 @@ function msg_event_test(scope, test) {
}
promise_test(msg_event_test.bind(this, 'no-current-extension-different-task'),
- 'Test calling waitUntil in a different task without an existing extension throws');
+ 'Test calling waitUntil in a task at the end of the event handler without an existing extension throws');
promise_test(msg_event_test.bind(this, 'no-current-extension-different-microtask'),
- 'Test calling waitUntil in a different microtask without an existing extension throws');
+ 'Test calling waitUntil in a microtask at the end of the event handler without an existing extension suceeds');
promise_test(msg_event_test.bind(this, 'current-extension-different-task'),
- 'Test calling waitUntil in a different task with an existing extension succeeds');
+ 'Test calling waitUntil in a different task an existing extension succeeds');
-promise_test(msg_event_test.bind(this, 'current-extension-expired-same-microtask-turn'),
- 'Test calling waitUntil with an existing extension promise handler succeeds');
+promise_test(msg_event_test.bind(this, 'during-event-dispatch-current-extension-expired-same-microtask-turn'),
+ 'Test calling waitUntil at the end of an existing extension promise handler succeeds (event is still being dispatched)');
-// The promise handler will queue a new microtask after the check for new
-// extensions was performed.
-promise_test(msg_event_test.bind(this, 'current-extension-expired-same-microtask-turn-extra'),
- 'Test calling waitUntil at the end of the microtask turn throws');
+promise_test(msg_event_test.bind(this, 'during-event-dispatch-current-extension-expired-same-microtask-turn-extra'),
+ 'Test calling waitUntil in a microtask at the end of an existing extension promise handler succeeds (event is still being dispatched)');
+
+promise_test(msg_event_test.bind(this, 'after-event-dispatch-current-extension-expired-same-microtask-turn'),
+ 'Test calling waitUntil in an existing extension promise handler succeeds (event is not being dispatched)');
+
+promise_test(msg_event_test.bind(this, 'after-event-dispatch-current-extension-expired-same-microtask-turn-extra'),
+ 'Test calling waitUntil in a microtask at the end of an existing extension promise handler throws (event is not being dispatched)');
promise_test(msg_event_test.bind(this, 'current-extension-expired-different-task'),
'Test calling waitUntil after the current extension expired in a different task fails');
@@ -80,24 +85,36 @@ promise_test(msg_event_test.bind(this, 'script-extendable-event'),
promise_test(function(t) {
var testBody = function(worker) {
- return with_iframe('./resources/pending-respondwith-async-waituntil/dummy.html');
+ return with_iframe('./resources/pending-respondwith-async-waituntil');
}
return runTest(t, 'pending-respondwith-async-waituntil', testBody);
}, 'Test calling waitUntil asynchronously with pending respondWith promise.');
promise_test(function(t) {
var testBody = function(worker) {
- return with_iframe('./resources/respondwith-microtask-sync-waituntil/dummy.html');
+ return with_iframe('./resources/during-event-dispatch-respondwith-microtask-sync-waituntil');
}
- return runTest(t, 'respondwith-microtask-sync-waituntil', testBody);
- }, 'Test calling waitUntil synchronously inside microtask of respondWith promise.');
+ return runTest(t, 'during-event-dispatch-respondwith-microtask-sync-waituntil', testBody);
+ }, 'Test calling waitUntil synchronously inside microtask of respondWith promise (event is being dispatched).');
promise_test(function(t) {
var testBody = function(worker) {
- return with_iframe('./resources/respondwith-microtask-async-waituntil/dummy.html');
+ return with_iframe('./resources/during-event-dispatch-respondwith-microtask-async-waituntil');
}
- return runTest(t, 'respondwith-microtask-async-waituntil', testBody);
- }, 'Test calling waitUntil asynchronously inside microtask of respondWith promise.');
+ return runTest(t, 'during-event-dispatch-respondwith-microtask-async-waituntil', testBody);
+ }, 'Test calling waitUntil asynchronously inside microtask of respondWith promise (event is being dispatched).');
+promise_test(function(t) {
+ var testBody = function(worker) {
+ return with_iframe('./resources/after-event-dispatch-respondwith-microtask-sync-waituntil');
+ }
+ return runTest(t, 'after-event-dispatch-respondwith-microtask-sync-waituntil', testBody);
+ }, 'Test calling waitUntil synchronously inside microtask of respondWith promise (event is not being dispatched).');
+promise_test(function(t) {
+ var testBody = function(worker) {
+ return with_iframe('./resources/after-event-dispatch-respondwith-microtask-async-waituntil');
+ }
+ return runTest(t, 'after-event-dispatch-respondwith-microtask-async-waituntil', testBody);
+ }, 'Test calling waitUntil asynchronously inside microtask of respondWith promise (event is not being dispatched).');
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html
index 87fa0467983..7842a829c9b 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html
@@ -1,36 +1,61 @@
+
+respondWith cannot be called asynchronously
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js
index abf54934a3b..8a975b0d2e9 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js
@@ -1,4 +1,12 @@
-// controlled by 'init'/'done' messages.
+// This worker calls waitUntil() and respondWith() asynchronously and
+// reports back to the test whether they threw.
+//
+// These test cases are confusing. Bear in mind that the event is active
+// (calling waitUntil() is allowed) if:
+// * The pending promise count is not 0, or
+// * The event dispatch flag is set.
+
+// Controlled by 'init'/'done' messages.
var resolveLockPromise;
var port;
@@ -14,34 +22,72 @@ self.addEventListener('message', function(event) {
case 'done':
resolveLockPromise();
break;
+
+ // Throws because waitUntil() is called in a task after event dispatch
+ // finishes.
case 'no-current-extension-different-task':
async_task_waituntil(event).then(reportResultExpecting('InvalidStateError'));
break;
+
+ // OK because waitUntil() is called in a microtask that runs after the
+ // event handler runs, while the event dispatch flag is still set.
case 'no-current-extension-different-microtask':
- async_microtask_waituntil(event).then(reportResultExpecting('InvalidStateError'));
+ async_microtask_waituntil(event).then(reportResultExpecting('OK'));
break;
+
+ // OK because the second waitUntil() is called while the first waitUntil()
+ // promise is still pending.
case 'current-extension-different-task':
event.waitUntil(new Promise((res) => { resolveTestPromise = res; }));
async_task_waituntil(event).then(reportResultExpecting('OK')).then(resolveTestPromise);
break;
- case 'current-extension-expired-same-microtask-turn':
+
+ // OK because all promises involved resolve "immediately", so the second
+ // waitUntil() is called during the microtask checkpoint at the end of
+ // event dispatching, when the event dispatch flag is still set.
+ case 'during-event-dispatch-current-extension-expired-same-microtask-turn':
waitPromise = Promise.resolve();
event.waitUntil(waitPromise);
waitPromise.then(() => { return sync_waituntil(event); })
.then(reportResultExpecting('OK'))
break;
- case 'current-extension-expired-same-microtask-turn-extra':
- // The promise handler queues a new microtask *after* the check for new
- // extensions was performed.
+
+ // OK for the same reason as above.
+ case 'during-event-dispatch-current-extension-expired-same-microtask-turn-extra':
waitPromise = Promise.resolve();
event.waitUntil(waitPromise);
+ waitPromise.then(() => { return async_microtask_waituntil(event); })
+ .then(reportResultExpecting('OK'))
+ break;
+
+
+ // OK because the pending promise count is decremented in a microtask
+ // queued upon fulfillment of the first waitUntil() promise, so the second
+ // waitUntil() is called while the pending promise count is still
+ // positive.
+ case 'after-event-dispatch-current-extension-expired-same-microtask-turn':
+ waitPromise = makeNewTaskPromise();
+ event.waitUntil(waitPromise);
+ waitPromise.then(() => { return sync_waituntil(event); })
+ .then(reportResultExpecting('OK'))
+ break;
+
+ // Throws because the second waitUntil() is called after the pending
+ // promise count was decremented to 0.
+ case 'after-event-dispatch-current-extension-expired-same-microtask-turn-extra':
+ waitPromise = makeNewTaskPromise();
+ event.waitUntil(waitPromise);
waitPromise.then(() => { return async_microtask_waituntil(event); })
.then(reportResultExpecting('InvalidStateError'))
break;
+
+ // Throws because the second waitUntil() is called in a new task, after
+ // first waitUntil() promise settled and the event dispatch flag is unset.
case 'current-extension-expired-different-task':
event.waitUntil(Promise.resolve());
async_task_waituntil(event).then(reportResultExpecting('InvalidStateError'));
break;
+
case 'script-extendable-event':
self.dispatchEvent(new ExtendableEvent('nontrustedevent'));
break;
@@ -51,25 +97,62 @@ self.addEventListener('message', function(event) {
});
self.addEventListener('fetch', function(event) {
- if (event.request.url.indexOf('pending-respondwith-async-waituntil') != -1) {
+ const path = new URL(event.request.url).pathname;
+ const step = path.substring(path.lastIndexOf('/') + 1);
+ let response;
+ switch (step) {
+ // OK because waitUntil() is called while the respondWith() promise is still
+ // unsettled, so the pending promise count is positive.
+ case 'pending-respondwith-async-waituntil':
var resolveFetch;
- let response = new Promise((res) => { resolveFetch = res; });
+ response = new Promise((res) => { resolveFetch = res; });
event.respondWith(response);
async_task_waituntil(event)
.then(reportResultExpecting('OK'))
.then(() => { resolveFetch(new Response('OK')); });
- } else if (event.request.url.indexOf('respondwith-microtask-sync-waituntil') != -1) {
+ break;
+
+ // OK because all promises involved resolve "immediately", so waitUntil() is
+ // called during the microtask checkpoint at the end of event dispatching,
+ // when the event dispatch flag is still set.
+ case 'during-event-dispatch-respondwith-microtask-sync-waituntil':
response = Promise.resolve(new Response('RESP'));
event.respondWith(response);
response.then(() => { return sync_waituntil(event); })
- .then(reportResultExpecting('OK'))
- } else if (event.request.url.indexOf('respondwith-microtask-async-waituntil') != -1) {
+ .then(reportResultExpecting('OK'));
+ break;
+
+ // OK because all promises involved resolve "immediately", so waitUntil() is
+ // called during the microtask checkpoint at the end of event dispatching,
+ // when the event dispatch flag is still set.
+ case 'during-event-dispatch-respondwith-microtask-async-waituntil':
response = Promise.resolve(new Response('RESP'));
event.respondWith(response);
+ response.then(() => { return async_microtask_waituntil(event); })
+ .then(reportResultExpecting('OK'));
+ break;
+
+ // OK because the pending promise count is decremented in a microtask queued
+ // upon fulfillment of the respondWith() promise, so waitUntil() is called
+ // while the pending promise count is still positive.
+ case 'after-event-dispatch-respondwith-microtask-sync-waituntil':
+ response = makeNewTaskPromise().then(() => {return new Response('RESP');});
+ event.respondWith(response);
+ response.then(() => { return sync_waituntil(event); })
+ .then(reportResultExpecting('OK'));
+ break;
+
+
+ // Throws because waitUntil() is called after the pending promise count was
+ // decremented to 0.
+ case 'after-event-dispatch-respondwith-microtask-async-waituntil':
+ response = makeNewTaskPromise().then(() => {return new Response('RESP');});
+ event.respondWith(response);
response.then(() => { return async_microtask_waituntil(event); })
.then(reportResultExpecting('InvalidStateError'))
- }
- });
+ break;
+ }
+});
self.addEventListener('nontrustedevent', function(event) {
sync_waituntil(event).then(reportResultExpecting('InvalidStateError'));
@@ -118,3 +201,10 @@ function async_task_waituntil(event) {
}, 0);
});
}
+
+// Returns a promise that settles in a separate task.
+function makeNewTaskPromise() {
+ return new Promise(resolve => {
+ setTimeout(resolve, 0);
+ });
+}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js
index 7f66d20dfc2..3409d0a0397 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js
@@ -1,19 +1,56 @@
-var result;
+// This worker attempts to call respondWith() asynchronously after the
+// fetch event handler finished. It reports back to the test whether
+// an exception was thrown.
-self.addEventListener('message', function(event) {
- event.data.port.postMessage(result);
+// These get reset at the start of a test case.
+let reportResult;
+let resultPromise;
+
+// The test page sends a message to tell us that a new test case is starting.
+// We expect a fetch event after this.
+self.addEventListener('message', (event) => {
+ resultPromise = new Promise((resolve) => {
+ reportResult = resolve;
});
+ // Keep the worker alive until the test case finishes, and report
+ // back the result to the test page.
+ event.waitUntil(resultPromise.then(result => {
+ event.source.postMessage(result);
+ }));
+});
+
+// Calls respondWith() and reports back whether an exception occurred.
+function tryRespondWith(event) {
+ try {
+ event.respondWith(new Response());
+ reportResult({didThrow: false});
+ } catch (error) {
+ reportResult({didThrow: true, error: error.name});
+ }
+}
+
+function respondWithInTask(event) {
+ setTimeout(() => {
+ tryRespondWith(event);
+ }, 0);
+}
+
+function respondWithInMicrotask(event) {
+ Promise.resolve().then(() => {
+ tryRespondWith(event);
+ });
+}
+
self.addEventListener('fetch', function(event) {
- setTimeout(function() {
- try {
- event.respondWith(new Response());
- result = 'FAIL: did not throw';
- } catch (error) {
- if (error.name == 'InvalidStateError')
- result = 'PASS';
- else
- result = 'FAIL: Unexpected exception: ' + error;
- }
- }, 0);
- });
+ const path = new URL(event.request.url).pathname;
+ const test = path.substring(path.lastIndexOf('/') + 1);
+
+ // If this is a test case, try respondWith() and report back to the test page
+ // the result.
+ if (test == 'respondWith-in-task') {
+ respondWithInTask(event);
+ } else if (test == 'respondWith-in-microtask') {
+ respondWithInMicrotask(event);
+ }
+});
diff --git a/tests/wpt/web-platform-tests/shape-detection/README.md b/tests/wpt/web-platform-tests/shape-detection/README.md
new file mode 100644
index 00000000000..556568baddb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/README.md
@@ -0,0 +1,44 @@
+The `shapedetection-helpers.js` tests require implementations of
+the `FaceDetectionTest` and `BarcodeDetectionTest` interfaces, which
+should emulate platform shape detection backends.
+
+The `FaceDetectionTest` interface is defined as:
+
+```
+ class FaceDetectionTest {
+ async initialize(); // Sets up the testing environment.
+ async reset(); // Frees the resources.
+ MockFaceDetectionProvider(); //Returns `MockFaceDetectionProvider` interface.
+ };
+
+ class MockFaceDetectionProvider {
+ getFrameData(); //Gets frame data of detection result.
+ getMaxDetectedFaces(); //Gets value of `maxDetectedFaces` in `FaceDetector` constructor
+ getFastMode(); //Gets value of `fastMode` in `FaceDetector` constructor
+ };
+```
+
+The Chromium implementation of the `FaceDetectionTest` interface is located in
+[mock-facedetection.js](../resources/chromium/mock-facedetection.js).
+
+The `BarcodeDetectionTest` interface is defined as:
+
+```
+ class BarcodeDetectionTest {
+ async initialize(); // Sets up the testing environment.
+ async reset(); // Frees the resources.
+ MockBarcodeDetectionProvider(); //Returns `MockBarcodeDetectionProvider` interface.
+ };
+
+ class MockBarcodeDetectionProvider {
+ async enumerateSupportedFormats(); //Enumerates supported formats
+ getFrameData(); //Gets frame data of detection result.
+ getFormats(); //Gets value of `formats` in `BarcodeDetector` constructor
+ };
+```
+
+The Chromium implementation of the `BarcodeDetectionTest` interface is located in
+[mock-barcodedetection.js](../resources/chromium/mock-barcodedetection.js).
+
+Other browser vendors should provide their own implementations of
+the `FaceDetectionTest` and `BarcodeDetectionTest` interfaces.
diff --git a/tests/wpt/web-platform-tests/shape-detection/detected-boundingBox-read-only.html b/tests/wpt/web-platform-tests/shape-detection/detected-boundingBox-read-only.html
new file mode 100644
index 00000000000..86b88892260
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detected-boundingBox-read-only.html
@@ -0,0 +1,51 @@
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-HTMLCanvasElement.html b/tests/wpt/web-platform-tests/shape-detection/detection-HTMLCanvasElement.html
new file mode 100644
index 00000000000..4e9615a03d0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-HTMLCanvasElement.html
@@ -0,0 +1,73 @@
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-HTMLImageElement.html b/tests/wpt/web-platform-tests/shape-detection/detection-HTMLImageElement.html
new file mode 100644
index 00000000000..979efabdcb0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-HTMLImageElement.html
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-HTMLVideoElement.html b/tests/wpt/web-platform-tests/shape-detection/detection-HTMLVideoElement.html
new file mode 100644
index 00000000000..7b3736d02e9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-HTMLVideoElement.html
@@ -0,0 +1,55 @@
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-ImageBitmap.html b/tests/wpt/web-platform-tests/shape-detection/detection-ImageBitmap.html
new file mode 100644
index 00000000000..a7157c0960e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-ImageBitmap.html
@@ -0,0 +1,54 @@
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-ImageData.html b/tests/wpt/web-platform-tests/shape-detection/detection-ImageData.html
new file mode 100644
index 00000000000..a74c2afbe1b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-ImageData.html
@@ -0,0 +1,56 @@
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-getSupportedFormats.html b/tests/wpt/web-platform-tests/shape-detection/detection-getSupportedFormats.html
new file mode 100644
index 00000000000..4ccb5ab7661
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-getSupportedFormats.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-on-worker.worker.js b/tests/wpt/web-platform-tests/shape-detection/detection-on-worker.worker.js
new file mode 100644
index 00000000000..6b440af7b81
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-on-worker.worker.js
@@ -0,0 +1,47 @@
+importScripts("/resources/testharness.js");
+importScripts("resources/shapedetection-helpers.js");
+
+'use strict';
+
+// These tests verify that a Detector's detect() works on an
+// ImageBitmap on workers.
+const imageBitmapTests =
+ [
+ {
+ createDetector: () => { return new FaceDetector(); },
+ mockTestName: "FaceDetectionTest",
+ resultSize: 3, // Number of faces
+ detectorType: "Face"
+ },
+ {
+ createDetector: () => { return new BarcodeDetector(); },
+ mockTestName: "BarcodeDetectionTest",
+ resultSize: 2, // Number of barcodes
+ detectorType: "Barcode"
+ }
+ ];
+
+for (let imageBitmapTest of imageBitmapTests) {
+ // ImageBitmap is of transferable type and can be sent to and
+ // tested on worker.
+ detection_test(imageBitmapTest.mockTestName, async (t, detectionTest) => {
+ const img = createTestImage();
+ const theImageBitmap = await createImageBitmap(img);
+ const detector = imageBitmapTest.createDetector();
+ const detectionResult = await detector.detect(theImageBitmap);
+ assert_equals(detectionResult.length, imageBitmapTest.resultSize,
+ `Number of ${imageBitmapTest.detectorType}`);
+ }, `${imageBitmapTest.detectorType} Detector detect(ImageBitmap) on worker`);
+}
+
+function createTestImage() {
+ const image = new OffscreenCanvas(100, 50);
+ const imgctx = image.getContext('2d');
+ imgctx.fillStyle = "#F00";
+ imgctx.fillRect(0, 0, 2, 2);
+ imgctx.fillStyle = "#0F0";
+ imgctx.fillRect(0, 0, 1, 1);
+ return image;
+}
+
+done();
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-options.html b/tests/wpt/web-platform-tests/shape-detection/detection-options.html
new file mode 100644
index 00000000000..31475575e3f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-options.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detection-security-test.html b/tests/wpt/web-platform-tests/shape-detection/detection-security-test.html
new file mode 100644
index 00000000000..b3f458e23ee
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detection-security-test.html
@@ -0,0 +1,74 @@
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/detector-same-object.html b/tests/wpt/web-platform-tests/shape-detection/detector-same-object.html
new file mode 100644
index 00000000000..52540271d27
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/detector-same-object.html
@@ -0,0 +1,55 @@
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/shape-detection/idlharness.any.js b/tests/wpt/web-platform-tests/shape-detection/idlharness.any.js
index ea772689105..dab7de99d2d 100644
--- a/tests/wpt/web-platform-tests/shape-detection/idlharness.any.js
+++ b/tests/wpt/web-platform-tests/shape-detection/idlharness.any.js
@@ -1,12 +1,54 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
+// META: script=/shape-detection/resources/shapedetection-helpers.js
// See: https://wicg.github.io/shape-detection-api/
-promise_test(async () => {
- const idl = await fetch('/interfaces/shape-detection-api.idl').then(r => r.text());
+'use strict';
- const idl_array = new IdlArray();
- idl_array.add_idls(idl);
- idl_array.test();
-}, 'Test shape-detection IDL interface');
+idl_test(
+ ['shape-detection-api'],
+ ['dom', 'geometry'],
+ async idl_array => {
+ let faceDetectionTest, barcodeDetectionTest;
+ try {
+ faceDetectionTest =
+ await initialize_detection_tests("FaceDetectionTest");
+ barcodeDetectionTest =
+ await initialize_detection_tests("BarcodeDetectionTest");
+ const img = createTestImage();
+ const theImageBitmap = await createImageBitmap(img);
+
+ self.faceDetector = new FaceDetector();
+ const faceDetectionResult = await faceDetector.detect(theImageBitmap);
+ self.detectedFace = faceDetectionResult[0];
+
+ self.barcodeDetector = new BarcodeDetector();
+ const barcodeDetectionResult =
+ await barcodeDetector.detect(theImageBitmap);
+ self.detectedBarcode = barcodeDetectionResult[0];
+ } catch (e) {
+ // Surfaced in idlharness.js's test_object below.
+ } finally {
+ faceDetectionTest.reset();
+ barcodeDetectionTest.reset();
+ }
+
+ idl_array.add_objects({
+ FaceDetector: ['faceDetector'],
+ DetectedFace: ['detectedFace'],
+ BarcodeDetector: ['barcodeDetector'],
+ DetectedBarcode: ['detectedBarcode']
+ });
+ }
+);
+
+function createTestImage() {
+ const image = new OffscreenCanvas(100, 50);
+ const imgctx = image.getContext('2d');
+ imgctx.fillStyle = "#F00";
+ imgctx.fillRect(0, 0, 2, 2);
+ imgctx.fillStyle = "#0F0";
+ imgctx.fillRect(0, 0, 1, 1);
+ return image;
+}
diff --git a/tests/wpt/web-platform-tests/shape-detection/resources/shapedetection-helpers.js b/tests/wpt/web-platform-tests/shape-detection/resources/shapedetection-helpers.js
new file mode 100644
index 00000000000..09cea09c6fe
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/resources/shapedetection-helpers.js
@@ -0,0 +1,91 @@
+'use strict';
+
+// These tests rely on the User Agent providing an implementation of
+// platform shape detection backends.
+//
+// In Chromium-based browsers this implementation is provided by a polyfill
+// in order to reduce the amount of test-only code shipped to users. To enable
+// these tests the browser must be run with these options:
+//
+// --enable-blink-features=MojoJS,MojoJSTest
+
+let loadChromiumResources = Promise.resolve().then(() => {
+ if (!MojoInterfaceInterceptor) {
+ // Do nothing on non-Chromium-based browsers or when the Mojo bindings are
+ // not present in the global namespace.
+ return;
+ }
+
+ const prefix = '/gen/services/shape_detection/public/mojom';
+ let chain = Promise.resolve();
+ [
+ '/gen/layout_test_data/mojo/public/js/mojo_bindings.js',
+ '/gen/mojo/public/mojom/base/big_buffer.mojom.js',
+ '/gen/skia/public/interfaces/image_info.mojom.js',
+ '/gen/skia/public/interfaces/bitmap.mojom.js',
+ '/gen/ui/gfx/geometry/mojo/geometry.mojom.js',
+ `${prefix}/barcodedetection.mojom.js`,
+ `${prefix}/barcodedetection_provider.mojom.js`,
+ `${prefix}/facedetection.mojom.js`,
+ `${prefix}/facedetection_provider.mojom.js`,
+ '/resources/chromium/mock-barcodedetection.js',
+ '/resources/chromium/mock-facedetection.js',
+ ].forEach(path => {
+ // Use importScripts for workers.
+ if (typeof document === 'undefined') {
+ chain = chain.then(() => importScripts(path));
+ return;
+ }
+ let script = document.createElement('script');
+ script.src = path;
+ script.async = false;
+ chain = chain.then(() => new Promise(resolve => {
+ script.onload = () => resolve();
+ }));
+ document.head.appendChild(script);
+ });
+
+ return chain;
+});
+
+/**
+ * @param {String} detectionTestName
+ * name of mock shape detection test interface,
+ * must be the item of ["FaceDetectionTest", "BarcodeDetectionTest"]
+*/
+async function initialize_detection_tests(detectionTestName) {
+ let detectionTest;
+ // Use 'self' for workers.
+ if (typeof document === 'undefined') {
+ if (typeof self[detectionTestName] === 'undefined') {
+ await loadChromiumResources;
+ }
+ detectionTest = new self[detectionTestName]();
+ } else {
+ if (typeof window[detectionTestName] === 'undefined') {
+ await loadChromiumResources;
+ }
+ detectionTest = new window[detectionTestName]();
+ }
+ await detectionTest.initialize();
+ return detectionTest;
+}
+
+function detection_test(detectionTestName, func, name, properties) {
+ promise_test(async t => {
+ let detectionTest = await initialize_detection_tests(detectionTestName);
+ try {
+ await func(t, detectionTest);
+ } finally {
+ await detectionTest.reset();
+ };
+ }, name, properties);
+}
+
+function getArrayBufferFromBigBuffer(bigBuffer) {
+ if (bigBuffer.$tag == mojoBase.mojom.BigBuffer.Tags.bytes) {
+ return new Uint8Array(bigBuffer.bytes).buffer;
+ }
+ return bigBuffer.sharedMemory.bufferHandle.mapBuffer(0,
+ bigBuffer.sharedMemory.size).buffer;
+}
diff --git a/tests/wpt/web-platform-tests/shape-detection/shapedetection-cross-origin.sub.html b/tests/wpt/web-platform-tests/shape-detection/shapedetection-cross-origin.sub.html
new file mode 100644
index 00000000000..c9d86430356
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/shapedetection-cross-origin.sub.html
@@ -0,0 +1,62 @@
+
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/shape-detection/shapedetection-empty-input.html b/tests/wpt/web-platform-tests/shape-detection/shapedetection-empty-input.html
new file mode 100644
index 00000000000..601c992ed85
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shape-detection/shapedetection-empty-input.html
@@ -0,0 +1,33 @@
+
+
+
+
\ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/appcache.manifest b/tests/wpt/web-platform-tests/signed-exchange/appcache/appcache.manifest
new file mode 100644
index 00000000000..adc0409be92
--- /dev/null
+++ b/tests/wpt/web-platform-tests/signed-exchange/appcache/appcache.manifest
@@ -0,0 +1,3 @@
+CACHE MANIFEST
+resources/appcached-url.html
+resources/sxg/sxg-location.sxg
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/appcached-url-in-sxg.html b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/appcached-url-in-sxg.html
new file mode 100644
index 00000000000..5f5defbedf0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/appcached-url-in-sxg.html
@@ -0,0 +1,10 @@
+
+Content of appcached URL
+
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/appcached-url.html b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/appcached-url.html
new file mode 100644
index 00000000000..d58617b64eb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/appcached-url.html
@@ -0,0 +1,10 @@
+
+Content of appcached URL
+
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/inner-url.html b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/inner-url.html
new file mode 100644
index 00000000000..5b247bbfe99
--- /dev/null
+++ b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/inner-url.html
@@ -0,0 +1,10 @@
+
+Content of fallback URL
+
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/__dir__.headers b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/__dir__.headers
new file mode 100644
index 00000000000..83a3c128cfe
--- /dev/null
+++ b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/__dir__.headers
@@ -0,0 +1,2 @@
+Content-Type: application/signed-exchange;v=b3
+X-Content-Type-Options: nosniff
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/sxg-appcached.sxg b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/sxg-appcached.sxg
new file mode 100644
index 00000000000..673adc20926
Binary files /dev/null and b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/sxg-appcached.sxg differ
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/sxg-location.sxg b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/sxg-location.sxg
new file mode 100644
index 00000000000..624e67362c5
Binary files /dev/null and b/tests/wpt/web-platform-tests/signed-exchange/appcache/resources/sxg/sxg-location.sxg differ
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/sxg-inner-resp-over-appcache.tentative.https.html b/tests/wpt/web-platform-tests/signed-exchange/appcache/sxg-inner-resp-over-appcache.tentative.https.html
new file mode 100644
index 00000000000..68edbede31f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/signed-exchange/appcache/sxg-inner-resp-over-appcache.tentative.https.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html b/tests/wpt/web-platform-tests/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html
new file mode 100644
index 00000000000..b9ca0ff61e5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/signed-exchange/resources/generate-test-sxgs.sh b/tests/wpt/web-platform-tests/signed-exchange/resources/generate-test-sxgs.sh
index e76286be991..64c28325d3a 100755
--- a/tests/wpt/web-platform-tests/signed-exchange/resources/generate-test-sxgs.sh
+++ b/tests/wpt/web-platform-tests/signed-exchange/resources/generate-test-sxgs.sh
@@ -43,6 +43,37 @@ gen-signedexchange \
-o sxg/sxg-location.sxg \
-miRecordSize 100
+# A valid Signed Exchange for appcache test.
+gen-signedexchange \
+ -version $sxg_version \
+ -uri $inner_url_origin/signed-exchange/appcache/resources/inner-url.html \
+ -status 200 \
+ -content sxg-location.html \
+ -certificate $certfile \
+ -certUrl $cert_url_origin/signed-exchange/resources/$certfile.cbor \
+ -validityUrl $inner_url_origin/signed-exchange/resources/resource.validity.msg \
+ -privateKey $keyfile \
+ -date 2018-04-01T00:00:00Z \
+ -expire 168h \
+ -o ../appcache/resources/sxg/sxg-location.sxg \
+ -miRecordSize 100
+
+# A valid Signed Exchange for appcache test
+# - appcache and the sxg inner resp both provide the content for the url
+gen-signedexchange \
+ -version $sxg_version \
+ -uri $inner_url_origin/signed-exchange/appcache/resources/appcached-url.html \
+ -status 200 \
+ -content ../appcache/resources/appcached-url-in-sxg.html \
+ -certificate $certfile \
+ -certUrl $cert_url_origin/signed-exchange/resources/$certfile.cbor \
+ -validityUrl $inner_url_origin/signed-exchange/resources/resource.validity.msg \
+ -privateKey $keyfile \
+ -date 2018-04-01T00:00:00Z \
+ -expire 168h \
+ -o ../appcache/resources/sxg/sxg-appcached.sxg \
+ -miRecordSize 100
+
# A valid Signed Exchange. The origin of certUrl is the "alt" origin where NEL
# policy is installed in reporting tests.
gen-signedexchange \
diff --git a/tests/wpt/web-platform-tests/svg/pservers/reftests/radialgradient-fully-overlapping.svg b/tests/wpt/web-platform-tests/svg/pservers/reftests/radialgradient-fully-overlapping.svg
index e16bb4ab917..5b5f7bd4c83 100644
--- a/tests/wpt/web-platform-tests/svg/pservers/reftests/radialgradient-fully-overlapping.svg
+++ b/tests/wpt/web-platform-tests/svg/pservers/reftests/radialgradient-fully-overlapping.svg
@@ -3,14 +3,14 @@
-
+
-
+
-
-
+
+
diff --git a/tests/wpt/web-platform-tests/svg/struct/reftests/reference/green-100x100.svg b/tests/wpt/web-platform-tests/svg/struct/reftests/reference/green-100x100.svg
new file mode 100644
index 00000000000..120941444a4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/svg/struct/reftests/reference/green-100x100.svg
@@ -0,0 +1,3 @@
+
diff --git a/tests/wpt/web-platform-tests/svg/struct/reftests/use-svg-dimensions-override-001.svg b/tests/wpt/web-platform-tests/svg/struct/reftests/use-svg-dimensions-override-001.svg
new file mode 100644
index 00000000000..c658adce80f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/svg/struct/reftests/use-svg-dimensions-override-001.svg
@@ -0,0 +1,18 @@
+
diff --git a/tests/wpt/web-platform-tests/svg/struct/reftests/use-svg-dimensions-override-002.svg b/tests/wpt/web-platform-tests/svg/struct/reftests/use-svg-dimensions-override-002.svg
new file mode 100644
index 00000000000..6c3f97b8dc4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/svg/struct/reftests/use-svg-dimensions-override-002.svg
@@ -0,0 +1,18 @@
+
+ 'width' and 'height' from <use> overrides values on referenced <svg>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/svg/struct/reftests/use-symbol-dimensions-override-001.svg b/tests/wpt/web-platform-tests/svg/struct/reftests/use-symbol-dimensions-override-001.svg
new file mode 100644
index 00000000000..1f8f7141478
--- /dev/null
+++ b/tests/wpt/web-platform-tests/svg/struct/reftests/use-symbol-dimensions-override-001.svg
@@ -0,0 +1,18 @@
+
+ 'width' and 'height' from <use> overrides values on referenced <symbol>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/svg/struct/reftests/use-symbol-dimensions-override-002.svg b/tests/wpt/web-platform-tests/svg/struct/reftests/use-symbol-dimensions-override-002.svg
new file mode 100644
index 00000000000..9c1fd49083a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/svg/struct/reftests/use-symbol-dimensions-override-002.svg
@@ -0,0 +1,18 @@
+
+ 'width' and 'height' from <use> overrides values on referenced <symbol>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/tools/ci/azure/affected_tests.yml b/tests/wpt/web-platform-tests/tools/ci/azure/affected_tests.yml
index 17fca51d50c..8076bc38698 100644
--- a/tests/wpt/web-platform-tests/tools/ci/azure/affected_tests.yml
+++ b/tests/wpt/web-platform-tests/tools/ci/azure/affected_tests.yml
@@ -16,7 +16,7 @@ steps:
- template: install_safari.yml
- template: update_hosts.yml
- template: update_manifest.yml
-- script: no_proxy='*' ./wpt run --yes --no-pause --no-fail-on-unexpected --no-restart-on-unexpected --affected ${{ parameters.affectedRange }} --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report.json --channel preview safari
+- script: no_proxy='*' ./wpt run --yes --no-pause --no-fail-on-unexpected --no-restart-on-unexpected --affected ${{ parameters.affectedRange }} --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report.json --log-wptscreenshot $(Build.ArtifactStagingDirectory)/wpt_screenshot.txt --channel preview safari
displayName: 'Run tests'
- task: PublishBuildArtifacts@1
displayName: 'Publish results'
diff --git a/tests/wpt/web-platform-tests/tools/ci/azure/fyi_hook.yml b/tests/wpt/web-platform-tests/tools/ci/azure/fyi_hook.yml
index ddfbe3d3cf8..5af16af31bc 100644
--- a/tests/wpt/web-platform-tests/tools/ci/azure/fyi_hook.yml
+++ b/tests/wpt/web-platform-tests/tools/ci/azure/fyi_hook.yml
@@ -12,7 +12,7 @@ jobs:
pool:
vmImage: 'ubuntu-16.04'
steps:
- - script: curl -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://wpt.fyi/api/checks/azure/$(Build.BuildId)
+ - script: curl -f -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://wpt.fyi/api/checks/azure/$(Build.BuildId)
displayName: 'Invoke wpt.fyi hook'
- - script: curl -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://staging.wpt.fyi/api/checks/azure/$(Build.BuildId)
+ - script: curl -f -s -S -d "artifact=${{ parameters.artifactName }}" -X POST https://staging.wpt.fyi/api/checks/azure/$(Build.BuildId)
displayName: 'Invoke staging.wpt.fyi hook'
diff --git a/tests/wpt/web-platform-tests/tools/ci/before_install.sh b/tests/wpt/web-platform-tests/tools/ci/before_install.sh
index ea53f969015..cde1879211b 100755
--- a/tests/wpt/web-platform-tests/tools/ci/before_install.sh
+++ b/tests/wpt/web-platform-tests/tools/ci/before_install.sh
@@ -1,6 +1,9 @@
#!/bin/bash
set -e
+export GITHUB_PULL_REQUEST=$TRAVIS_PULL_REQUEST
+export GITHUB_BRANCH=$TRAVIS_BRANCH
+
if [[ $RUN_JOB -eq 1 ]] || ./wpt test-jobs --includes $JOB; then
export RUN_JOB=1
git submodule update --init --recursive 1>&2
diff --git a/tests/wpt/web-platform-tests/tools/ci/ci_resources_unittest.sh b/tests/wpt/web-platform-tests/tools/ci/ci_resources_unittest.sh
index f1d0389b2d6..11190fc58d6 100755
--- a/tests/wpt/web-platform-tests/tools/ci/ci_resources_unittest.sh
+++ b/tests/wpt/web-platform-tests/tools/ci/ci_resources_unittest.sh
@@ -5,13 +5,9 @@ SCRIPT_DIR=$(cd $(dirname "$0") && pwd -P)
WPT_ROOT=$SCRIPT_DIR/../..
cd $WPT_ROOT
-source tools/ci/lib.sh
-
main() {
- hosts_fixup
-
cd $WPT_ROOT
- pip install -U tox
+ pip install --user -U tox
./wpt install firefox browser --destination $HOME
./wpt install firefox webdriver --destination $HOME/firefox
export PATH=$HOME/firefox:$PATH
diff --git a/tests/wpt/web-platform-tests/tools/ci/ci_tools_unittest.sh b/tests/wpt/web-platform-tests/tools/ci/ci_tools_unittest.sh
index 55afb9f4331..366dcf66de8 100755
--- a/tests/wpt/web-platform-tests/tools/ci/ci_tools_unittest.sh
+++ b/tests/wpt/web-platform-tests/tools/ci/ci_tools_unittest.sh
@@ -19,7 +19,7 @@ run_applicable_tox () {
}
if ./wpt test-jobs --includes tools_unittest; then
- pip install -U tox codecov
+ pip install --user -U tox codecov
cd tools
run_applicable_tox
cd $WPT_ROOT
diff --git a/tests/wpt/web-platform-tests/tools/ci/ci_wpt.sh b/tests/wpt/web-platform-tests/tools/ci/ci_wpt.sh
index 5af04110b20..7c37e7863e0 100755
--- a/tests/wpt/web-platform-tests/tools/ci/ci_wpt.sh
+++ b/tests/wpt/web-platform-tests/tools/ci/ci_wpt.sh
@@ -5,13 +5,9 @@ SCRIPT_DIR=$(cd $(dirname "$0") && pwd -P)
WPT_ROOT=$SCRIPT_DIR/../..
cd $WPT_ROOT
-source tools/ci/lib.sh
-
main() {
git fetch --quiet --unshallow https://github.com/web-platform-tests/wpt.git +refs/heads/*:refs/remotes/origin/*
- hosts_fixup
- install_chrome unstable
- pip install -U tox codecov
+ pip install --user -U tox codecov
cd tools/wpt
tox
}
diff --git a/tests/wpt/web-platform-tests/tools/ci/ci_wptrunner_infrastructure.sh b/tests/wpt/web-platform-tests/tools/ci/ci_wptrunner_infrastructure.sh
index 267bf17525a..f3ce3e73ea7 100755
--- a/tests/wpt/web-platform-tests/tools/ci/ci_wptrunner_infrastructure.sh
+++ b/tests/wpt/web-platform-tests/tools/ci/ci_wptrunner_infrastructure.sh
@@ -5,7 +5,9 @@ SCRIPT_DIR=$(cd $(dirname "$0") && pwd -P)
WPT_ROOT=$SCRIPT_DIR/../..
cd $WPT_ROOT
-source tools/ci/lib.sh
+add_wpt_hosts() {
+ ./wpt make-hosts-file | sudo tee -a /etc/hosts
+}
test_infrastructure() {
local ARGS="";
@@ -21,13 +23,8 @@ main() {
PRODUCTS=( "firefox" "chrome" )
./wpt manifest --rebuild -p ~/meta/MANIFEST.json
for PRODUCT in "${PRODUCTS[@]}"; do
- if [ "$PRODUCT" != "firefox" ]; then
- # Firefox is expected to work using pref settings for DNS
- # Don't adjust the hostnames in that case to ensure this keeps working
- hosts_fixup
- fi
if [[ "$PRODUCT" == "chrome" ]]; then
- install_chrome unstable
+ add_wpt_hosts
test_infrastructure "--binary=$(which google-chrome-unstable)"
else
test_infrastructure
diff --git a/tests/wpt/web-platform-tests/tools/ci/lib.sh b/tests/wpt/web-platform-tests/tools/ci/lib.sh
deleted file mode 100644
index 8d5e6aef73b..00000000000
--- a/tests/wpt/web-platform-tests/tools/ci/lib.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-hosts_fixup() {
- echo "travis_fold:start:hosts_fixup"
- echo "Rewriting hosts file"
- echo "## /etc/hosts ##"
- cat /etc/hosts
- sudo sed -i 's/^::1\s*localhost/::1/' /etc/hosts
- ./wpt make-hosts-file | sudo tee -a /etc/hosts
- echo "== /etc/hosts =="
- cat /etc/hosts
- echo "----------------"
- echo "travis_fold:end:hosts_fixup"
-}
-
-install_chrome() {
- channel=$1
- deb_archive=google-chrome-${channel}_current_amd64.deb
- wget -q https://dl.google.com/linux/direct/$deb_archive
-
- # If the environment provides an installation of Google Chrome, the
- # existing binary may take precedence over the one introduced in this
- # script. Remove any previously-existing "alternatives" prior to
- # installation in order to ensure that the new binary is installed as
- # intended.
- if sudo update-alternatives --list google-chrome; then
- sudo update-alternatives --remove-all google-chrome
- fi
-
- # Installation will fail in cases where the package has unmet dependencies.
- # When this occurs, attempt to use the system package manager to fetch the
- # required packages and retry.
- if ! sudo dpkg --install $deb_archive; then
- sudo apt-get install --fix-broken
- sudo dpkg --install $deb_archive
- fi
-}
diff --git a/tests/wpt/web-platform-tests/tools/ci/run_tc.py b/tests/wpt/web-platform-tests/tools/ci/run_tc.py
new file mode 100755
index 00000000000..53b0870ea9f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/ci/run_tc.py
@@ -0,0 +1,261 @@
+#!/usr/bin/env python
+
+"""Wrapper script for running jobs in TaskCluster
+
+This is intended for running test jobs in TaskCluster. The script
+takes a two positional arguments which are the name of the test job
+and the script to actually run.
+
+The name of the test job is used to determine whether the script should be run
+for this push (this is in lieu of having a proper decision task). There are
+several ways that the script can be scheduled to run
+
+1. The output of wpt test-jobs includes the job name
+2. The job name is included in a job declaration (see below)
+3. The string "all" is included in the job declaration
+4. The job name is set to "all"
+
+A job declaration is a line appearing in the pull request body (for
+pull requests) or first commit message (for pushes) of the form:
+
+tc-jobs: job1,job2,[...]
+
+In addition, there are a number of keyword arguments used to set options for the
+environment in which the jobs run. Documentation for these is in the command help.
+
+As well as running the script, the script sets two environment variables;
+GITHUB_BRANCH which is the branch that the commits will merge into (if it's a PR)
+or the branch that the commits are on (if it's a push), and GITHUB_PULL_REQUEST
+which is the string "false" if the event triggering this job wasn't a pull request
+or the pull request number if it was. The semantics of these variables are chosen
+to match the corresponding TRAVIS_* variables.
+
+Note: for local testing in the Docker image the script ought to still work, but
+full functionality requires that the TASK_EVENT environment variable is set to
+the serialization of a GitHub event payload.
+"""
+
+import argparse
+import json
+import os
+import re
+import subprocess
+import sys
+try:
+ from urllib2 import urlopen
+except ImportError:
+ # Python 3 case
+ from urllib.request import urlopen
+
+
+root = os.path.abspath(
+ os.path.join(os.path.dirname(__file__),
+ os.pardir,
+ os.pardir))
+
+
+def run(cmd, return_stdout=False, **kwargs):
+ print(" ".join(cmd))
+ if return_stdout:
+ f = subprocess.check_output
+ else:
+ f = subprocess.check_call
+ return f(cmd, **kwargs)
+
+
+def start(cmd):
+ print(" ".join(cmd))
+ subprocess.Popen(cmd)
+
+
+def get_parser():
+ p = argparse.ArgumentParser()
+ p.add_argument("--oom-killer",
+ action="store_true",
+ default=False,
+ help="Run userspace OOM killer")
+ p.add_argument("--hosts",
+ dest="hosts_file",
+ action="store_true",
+ default=True,
+ help="Setup wpt entries in hosts file")
+ p.add_argument("--no-hosts",
+ dest="hosts_file",
+ action="store_false",
+ help="Don't setup wpt entries in hosts file")
+ p.add_argument("--browser",
+ action="append",
+ default=[],
+ help="Browsers that will be used in the job")
+ p.add_argument("--channel",
+ default=None,
+ choices=["experimental", "dev", "nightly", "beta", "stable"],
+ help="Chrome browser channel")
+ p.add_argument("--xvfb",
+ action="store_true",
+ help="Start xvfb")
+ p.add_argument("--checkout",
+ help="Revision to checkout before starting job")
+ p.add_argument("job",
+ help="Name of the job associated with the current event")
+ p.add_argument("script",
+ help="Script to run for the job")
+ p.add_argument("script_args",
+ nargs=argparse.REMAINDER,
+ help="Additional arguments to pass to the script")
+ return p
+
+
+def start_userspace_oom_killer():
+ # Start userspace OOM killer: https://github.com/rfjakob/earlyoom
+ # It will report memory usage every minute and prefer to kill browsers.
+ start(["sudo", "earlyoom", "-p", "-r", "60" "--prefer=(chrome|firefox)", "--avoid=python"])
+
+
+def make_hosts_file():
+ subprocess.check_call(["sudo", "sh", "-c", "./wpt make-hosts-file >> /etc/hosts"])
+
+
+def checkout_revision(rev):
+ subprocess.check_call(["git", "checkout", "-q", rev])
+
+
+def install_chrome(channel):
+ if channel in ("experimental", "dev", "nightly"):
+ deb_archive = "google-chrome-unstable_current_amd64.deb"
+ elif channel == "beta":
+ deb_archive = "google-chrome-beta_current_amd64.deb"
+ elif channel == "stable":
+ deb_archive = "google-chrome-stable_current_amd64.deb"
+ else:
+ raise ValueError("Unrecognized release channel: %s" % channel)
+
+ dest = os.path.join("/tmp", deb_archive)
+ resp = urlopen("https://dl.google.com/linux/direct/%s" % deb_archive)
+ with open(dest, "w") as f:
+ f.write(resp.read())
+
+ subprocess.check_call(["sudo", "apt-get", "-qqy", "update"])
+ subprocess.check_call(["sudo", "gdebi", "-n", "/tmp/%s" % deb_archive])
+
+
+def start_xvfb():
+ start(["sudo", "Xvfb", os.environ["DISPLAY"], "-screen", "0",
+ "%sx%sx%s" % (os.environ["SCREEN_WIDTH"],
+ os.environ["SCREEN_HEIGHT"],
+ os.environ["SCREEN_DEPTH"])])
+ start(["sudo", "fluxbox", "-display", os.environ["DISPLAY"]])
+
+
+def get_extra_jobs(event):
+ body = None
+ jobs = set()
+ if "commits" in event:
+ body = event["commits"][0]["message"]
+ elif "pull_request" in event:
+ body = event["pull_request"]["body"]
+
+ if not body:
+ return jobs
+
+ regexp = re.compile(r"\s*tc-jobs:(.*)$")
+
+ for line in body.splitlines():
+ m = regexp.match(line)
+ if m:
+ items = m.group(1)
+ for item in items.split(","):
+ jobs.add(item.strip())
+ break
+ return jobs
+
+
+def set_variables(event):
+ # Set some variables that we use to get the commits on the current branch
+ ref_prefix = "refs/heads/"
+ pull_request = "false"
+ branch = None
+ if "pull_request" in event:
+ pull_request = str(event["pull_request"]["number"])
+ # Note that this is the branch that a PR will merge to,
+ # not the branch name for the PR
+ branch = event["pull_request"]["base"]["ref"]
+ elif "ref" in event:
+ branch = event["ref"]
+ if branch.startswith(ref_prefix):
+ branch = branch[len(ref_prefix):]
+
+ os.environ["GITHUB_PULL_REQUEST"] = pull_request
+ if branch:
+ os.environ["GITHUB_BRANCH"] = branch
+
+
+def include_job(job):
+ jobs_str = run([os.path.join(root, "wpt"),
+ "test-jobs"], return_stdout=True)
+ print(jobs_str)
+ return job in set(jobs_str.splitlines())
+
+
+def setup_environment(args):
+ if args.hosts_file:
+ make_hosts_file()
+
+ if "chrome" in args.browser:
+ assert args.channel is not None
+ install_chrome(args.channel)
+
+ if args.xvfb:
+ start_xvfb()
+
+ if args.oom_killer:
+ start_userspace_oom_killer()
+
+ if args.checkout:
+ checkout_revision(args.checkout)
+
+
+def main():
+ args = get_parser().parse_args()
+ try:
+ event = json.loads(os.environ["TASK_EVENT"])
+ except KeyError:
+ # For example under local testing
+ event = {}
+
+ if event:
+ set_variables(event)
+
+ if os.environ.get("GITHUB_BRANCH"):
+ # Ensure that the remote base branch exists
+ # TODO: move this somewhere earlier in the task
+ run(["git", "fetch", "origin", "%s:%s" % (os.environ["GITHUB_BRANCH"],
+ os.environ["GITHUB_BRANCH"])])
+
+ extra_jobs = get_extra_jobs(event)
+
+ job = args.job
+
+ run_if = [(lambda: job == "all", "job set to 'all'"),
+ (lambda:"all" in extra_jobs, "Manually specified jobs includes 'all'"),
+ (lambda:job in extra_jobs, "Manually specified jobs includes '%s'" % job),
+ (lambda:include_job(job), "CI required jobs includes '%s'" % job)]
+
+ for fn, msg in run_if:
+ if fn():
+ print(msg)
+ break
+ else:
+ print("Job not scheduled for this push")
+ return
+
+ # Run the job
+ setup_environment(args)
+ os.chdir(root)
+ cmd = [args.script] + args.script_args
+ print(cmd)
+ sys.exit(subprocess.call(cmd))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/wpt/web-platform-tests/tools/ci/start.sh b/tests/wpt/web-platform-tests/tools/ci/start.sh
index 98c368427f6..18e2784e6cd 100644
--- a/tests/wpt/web-platform-tests/tools/ci/start.sh
+++ b/tests/wpt/web-platform-tests/tools/ci/start.sh
@@ -1,31 +1 @@
-# This script is designed to be sourced from tools/docker/start.sh
-
-# Start userspace OOM killer: https://github.com/rfjakob/earlyoom
-# It will report memory usage every minute and prefer to kill browsers.
-sudo earlyoom -p -r 60 --prefer '(chrome|firefox)' --avoid 'python' &
-
-sudo sh -c './wpt make-hosts-file >> /etc/hosts'
-
-if [[ $BROWSER == "chrome" ]] || [[ "$BROWSER" == all ]]
-then
- # Install Chrome dev
- if [[ "$CHANNEL" == "dev" ]] || [[ "$CHANNEL" == "nightly" ]]
- then
- deb_archive=google-chrome-unstable_current_amd64.deb
- elif [[ "$CHANNEL" == "beta" ]]
- then
- deb_archive=google-chrome-beta_current_amd64.deb
- elif [[ "$CHANNEL" == "stable" ]]
- then
- deb_archive=google-chrome-stable_current_amd64.deb
- else
- echo Unrecognized release channel: $CHANNEL >&2
- exit 1
- fi
- wget -O /tmp/$deb_archive https://dl.google.com/linux/direct/$deb_archive
-
- sudo apt-get -qqy update && sudo gdebi -n /tmp/$deb_archive
-fi
-
-sudo Xvfb $DISPLAY -screen 0 ${SCREEN_WIDTH}x${SCREEN_HEIGHT}x${SCREEN_DEPTH} &
-sudo fluxbox -display $DISPLAY &
+# Contents of this script superceeded by tools/ci/run_tc.py
diff --git a/tests/wpt/web-platform-tests/tools/ci/tests/test_run_tc.py b/tests/wpt/web-platform-tests/tools/ci/tests/test_run_tc.py
new file mode 100644
index 00000000000..436dc79670e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/ci/tests/test_run_tc.py
@@ -0,0 +1,33 @@
+import pytest
+
+from six import iteritems
+
+from tools.ci import run_tc
+
+
+@pytest.mark.parametrize("msg,expected", [
+ ("Some initial line\n\ntc-jobs:foo,bar", set(["foo", "bar"])),
+ ("Some initial line\n\ntc-jobs:foo, bar", set(["foo", "bar"])),
+ ("tc-jobs:foo, bar \nbaz", set(["foo", "bar"])),
+ ("tc-jobs:all", set(["all"])),
+ ("", set()),
+ ("tc-jobs:foo\ntc-jobs:bar", set(["foo"]))])
+@pytest.mark.parametrize("event", [
+ {"commits": [{"message": ""}]},
+ {"pull_request": {"body": ""}}
+])
+def test_extra_jobs_pr(msg, expected, event):
+ def sub(obj):
+ """Copy obj, except if it's a string with the value
+ replace it with the value of the msg argument"""
+ if isinstance(obj, dict):
+ return {key: sub(value) for (key, value) in iteritems(obj)}
+ elif isinstance(obj, list):
+ return [sub(value) for value in obj]
+ elif obj == "":
+ return msg
+ return obj
+
+ event = sub(event)
+
+ assert run_tc.get_extra_jobs(event) == expected
diff --git a/tests/wpt/web-platform-tests/tools/docker/Dockerfile b/tests/wpt/web-platform-tests/tools/docker/Dockerfile
index 0cb2352e5fd..e60b4ea6a3a 100644
--- a/tests/wpt/web-platform-tests/tools/docker/Dockerfile
+++ b/tests/wpt/web-platform-tests/tools/docker/Dockerfile
@@ -46,6 +46,12 @@ ENV TZ "UTC"
RUN echo "${TZ}" > /etc/timezone \
&& dpkg-reconfigure --frontend noninteractive tzdata
+# Set the locale
+RUN locale-gen en_US.UTF-8
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US:en
+ENV LC_ALL en_US.UTF-8
+
RUN useradd test \
--shell /bin/bash \
--create-home \
@@ -68,7 +74,7 @@ RUN sudo echo ""
RUN mkdir -p /home/test/artifacts
RUN mkdir -p /home/test/bin
-ENV PATH="/home/test/bin:${PATH}"
+ENV PATH="/home/test/bin:/home/test/.local/bin:${PATH}"
WORKDIR /home/test/
diff --git a/tests/wpt/web-platform-tests/tools/manifest/manifest.py b/tests/wpt/web-platform-tests/tools/manifest/manifest.py
index 90655daca22..f5d939fa132 100644
--- a/tests/wpt/web-platform-tests/tools/manifest/manifest.py
+++ b/tests/wpt/web-platform-tests/tools/manifest/manifest.py
@@ -1,4 +1,5 @@
import itertools
+import json
import os
from collections import defaultdict
from six import iteritems, iterkeys, itervalues, string_types
@@ -10,11 +11,9 @@ from .log import get_logger
from .utils import from_os_path, to_os_path
try:
- import ujson as json
- JSON_LIBRARY = 'ujson'
+ import ujson as fast_json
except ImportError:
- import json
- JSON_LIBRARY = 'json'
+ fast_json = json
CURRENT_VERSION = 5
@@ -436,7 +435,7 @@ def _load(logger, tests_root, manifest, types=None, meta_filters=None, allow_cac
try:
with open(manifest) as f:
rv = Manifest.from_json(tests_root,
- json.load(f),
+ fast_json.load(f),
types=types,
meta_filters=meta_filters)
except IOError:
@@ -446,7 +445,7 @@ def _load(logger, tests_root, manifest, types=None, meta_filters=None, allow_cac
return None
else:
rv = Manifest.from_json(tests_root,
- json.load(manifest),
+ fast_json.load(manifest),
types=types,
meta_filters=meta_filters)
@@ -504,12 +503,8 @@ def write(manifest, manifest_path):
if not os.path.exists(dir_name):
os.makedirs(dir_name)
with open(manifest_path, "wb") as f:
- if JSON_LIBRARY == 'ujson':
- # ujson does not support the separators flag.
- json.dump(manifest.to_json(), f, sort_keys=True, indent=1)
- else:
- # Use ',' instead of the default ', ' separator to prevent trailing
- # spaces: https://docs.python.org/2/library/json.html#json.dump
- json.dump(manifest.to_json(), f,
- sort_keys=True, indent=1, separators=(',', ': '))
+ # Use ',' instead of the default ', ' separator to prevent trailing
+ # spaces: https://docs.python.org/2/library/json.html#json.dump
+ json.dump(manifest.to_json(), f,
+ sort_keys=True, indent=1, separators=(',', ': '))
f.write("\n")
diff --git a/tests/wpt/web-platform-tests/tools/wpt/browser.py b/tests/wpt/web-platform-tests/tools/wpt/browser.py
index c4469800608..f5bc7c0af02 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/browser.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/browser.py
@@ -29,7 +29,7 @@ class Browser(object):
return NotImplemented
@abstractmethod
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
"""Install the WebDriver implementation for this browser."""
return NotImplemented
@@ -166,11 +166,11 @@ class Firefox(Browser):
os.remove(installer_path)
return self.find_binary_path(dest)
- def find_binary_path(self,path=None, channel="nightly"):
+ def find_binary_path(self, path=None, channel="nightly"):
"""Looks for the firefox binary in the virtual environment"""
if path is None:
- #os.getcwd() doesn't include the venv path
+ # os.getcwd() doesn't include the venv path
path = os.path.join(os.getcwd(), "_venv", "browsers", channel)
binary = None
@@ -315,7 +315,7 @@ class Firefox(Browser):
assert latest_release != 0
return "v%s.%s.%s" % tuple(str(item) for item in latest_release)
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
"""Install latest Geckodriver."""
if dest is None:
dest = os.getcwd()
@@ -392,7 +392,7 @@ class Fennec(Browser):
def find_webdriver(self, channel=None):
raise NotImplementedError
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
raise NotImplementedError
def version(self, binary=None, webdriver_binary=None):
@@ -440,24 +440,66 @@ class Chrome(Browser):
return "%s%s" % (platform, bits)
+ def chromium_platform_string(self):
+ platform = {
+ "Linux": "Linux",
+ "Windows": "Win",
+ "Darwin": "Mac"
+ }.get(uname[0])
+
+ if platform is None:
+ raise ValueError("Unable to construct a valid Chromium package name for current platform")
+
+ if (platform == "Linux" or platform == "Win") and uname[4] == "x86_64":
+ platform += "_x64"
+
+ return platform
+
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self, channel=None):
return find_executable("chromedriver")
- def install_webdriver(self, dest=None, channel=None):
+ def _latest_chromedriver_url(self, browser_binary=None):
+ latest = None
+ chrome_version = self.version(browser_binary)
+ if chrome_version is not None:
+ parts = chrome_version.split(".")
+ if len(parts) == 4:
+ latest_url = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_%s.%s.%s" % (
+ parts[0], parts[1], parts[2])
+ try:
+ latest = get(latest_url).text.strip()
+ except requests.RequestException:
+ latest_url = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_%s" % parts[0]
+ try:
+ latest = get(latest_url).text.strip()
+ except requests.RequestException:
+ pass
+ if latest is None:
+ # Fall back to the tip-of-tree *Chromium* build.
+ latest_url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/LAST_CHANGE" % (
+ self.chromium_platform_string())
+ latest = get(latest_url).text.strip()
+ url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/%s/chromedriver_%s.zip" % (
+ self.chromium_platform_string(), latest, self.platform_string())
+ else:
+ url = "https://chromedriver.storage.googleapis.com/%s/chromedriver_%s.zip" % (
+ latest, self.platform_string())
+ return url
+
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
if dest is None:
dest = os.pwd
- latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE").text.strip()
- url = "http://chromedriver.storage.googleapis.com/%s/chromedriver_%s.zip" % (latest,
- self.platform_string())
+ url = self._latest_chromedriver_url(browser_binary)
+ self.logger.info("Downloading ChromeDriver from %s" % url)
unzip(get(url).raw, dest)
-
- path = find_executable("chromedriver", dest)
- st = os.stat(path)
- os.chmod(path, st.st_mode | stat.S_IEXEC)
- return path
+ chromedriver_dir = os.path.join(dest, 'chromedriver_%s' % self.platform_string())
+ if os.path.isfile(os.path.join(chromedriver_dir, "chromedriver")):
+ shutil.move(os.path.join(chromedriver_dir, "chromedriver"), dest)
+ shutil.rmtree(chromedriver_dir)
+ return find_executable("chromedriver", dest)
def version(self, binary=None, webdriver_binary=None):
binary = binary or self.binary
@@ -465,11 +507,11 @@ class Chrome(Browser):
try:
version_string = call(binary, "--version").strip()
except subprocess.CalledProcessError:
- self.logger.warning("Failed to call %s", binary)
+ self.logger.warning("Failed to call %s" % binary)
return None
- m = re.match(r"Google Chrome (.*)", version_string)
+ m = re.match(r"(?:Google Chrome|Chromium) (.*)", version_string)
if not m:
- self.logger.warning("Failed to extract version from: %s", version_string)
+ self.logger.warning("Failed to extract version from: %s" % version_string)
return None
return m.group(1)
self.logger.warning("Unable to extract version from binary on Windows.")
@@ -494,13 +536,14 @@ class ChromeAndroid(Browser):
def find_webdriver(self, channel=None):
return find_executable("chromedriver")
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
chrome = Chrome()
return chrome.install_webdriver(dest, channel)
def version(self, binary=None, webdriver_binary=None):
return None
+
class Opera(Browser):
"""Opera-specific interface.
@@ -546,7 +589,7 @@ class Opera(Browser):
def find_webdriver(self, channel=None):
return find_executable("operadriver")
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
if dest is None:
dest = os.pwd
latest = get("https://api.github.com/repos/operasoftware/operachromiumdriver/releases/latest").json()["tag_name"]
@@ -569,7 +612,7 @@ class Opera(Browser):
try:
output = call(binary, "--version")
except subprocess.CalledProcessError:
- self.logger.warning("Failed to call %s", binary)
+ self.logger.warning("Failed to call %s" % binary)
return None
m = re.search(r"[0-9\.]+( [a-z]+)?$", output.strip())
if m:
@@ -591,7 +634,7 @@ class Edge(Browser):
def find_webdriver(self, channel=None):
return find_executable("MicrosoftWebDriver")
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
raise NotImplementedError
def version(self, binary=None, webdriver_binary=None):
@@ -599,9 +642,10 @@ class Edge(Browser):
try:
return call("powershell.exe", command).strip()
except (subprocess.CalledProcessError, OSError):
- self.logger.warning("Failed to call %s in PowerShell", command)
+ self.logger.warning("Failed to call %s in PowerShell" % command)
return None
+
class EdgeWebDriver(Edge):
product = "edge_webdriver"
@@ -621,7 +665,7 @@ class InternetExplorer(Browser):
def find_webdriver(self, channel=None):
return find_executable("IEDriverServer.exe")
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
raise NotImplementedError
def version(self, binary=None, webdriver_binary=None):
@@ -649,7 +693,7 @@ class Safari(Browser):
path = "/Applications/Safari Technology Preview.app/Contents/MacOS"
return find_executable("safaridriver", path)
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
raise NotImplementedError
def version(self, binary=None, webdriver_binary=None):
@@ -663,11 +707,11 @@ class Safari(Browser):
try:
version_string = call(webdriver_binary, "--version").strip()
except subprocess.CalledProcessError:
- self.logger.warning("Failed to call %s --version", webdriver_binary)
+ self.logger.warning("Failed to call %s --version" % webdriver_binary)
return None
m = re.match(r"Included with Safari (.*)", version_string)
if not m:
- self.logger.warning("Failed to extract version from: %s", version_string)
+ self.logger.warning("Failed to extract version from: %s" % version_string)
return None
return m.group(1)
@@ -721,7 +765,7 @@ class Servo(Browser):
def find_webdriver(self, channel=None):
return None
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
raise NotImplementedError
def version(self, binary=None, webdriver_binary=None):
@@ -751,7 +795,7 @@ class Sauce(Browser):
def find_webdriver(self, channel=None):
raise NotImplementedError
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
raise NotImplementedError
def version(self, binary=None, webdriver_binary=None):
@@ -773,7 +817,7 @@ class WebKit(Browser):
def find_webdriver(self, channel=None):
return None
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
raise NotImplementedError
def version(self, binary=None, webdriver_binary=None):
@@ -795,7 +839,7 @@ class Epiphany(Browser):
def find_webdriver(self, channel=None):
return find_executable("WebKitWebDriver")
- def install_webdriver(self, dest=None, channel=None):
+ def install_webdriver(self, dest=None, channel=None, browser_binary=None):
raise NotImplementedError
def version(self, binary=None, webdriver_binary=None):
diff --git a/tests/wpt/web-platform-tests/tools/wpt/run.py b/tests/wpt/web-platform-tests/tools/wpt/run.py
index a19851d14c5..1178c5a3f6d 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/run.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/run.py
@@ -266,7 +266,7 @@ class Chrome(BrowserSetup):
if install:
logger.info("Downloading chromedriver")
- webdriver_binary = self.browser.install_webdriver(dest=self.venv.bin_path)
+ webdriver_binary = self.browser.install_webdriver(dest=self.venv.bin_path, browser_binary=kwargs["binary"])
else:
logger.info("Using webdriver binary %s" % webdriver_binary)
@@ -284,6 +284,9 @@ class Chrome(BrowserSetup):
# Allow WebRTC tests to call getUserMedia.
kwargs["binary_args"] += ["--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream"]
+ # Shorten delay for Reporting .
+ kwargs["binary_args"].append("--short-reporting-delay")
+
class ChromeAndroid(BrowserSetup):
name = "chrome_android"
diff --git a/tests/wpt/web-platform-tests/tools/wpt/testfiles.py b/tests/wpt/web-platform-tests/tools/wpt/testfiles.py
index 70e695aa010..006e4a22d0b 100644
--- a/tests/wpt/web-platform-tests/tools/wpt/testfiles.py
+++ b/tests/wpt/web-platform-tests/tools/wpt/testfiles.py
@@ -34,15 +34,15 @@ def display_branch_point():
def branch_point():
git = get_git_cmd(wpt_root)
- if (os.environ.get("TRAVIS_PULL_REQUEST", "false") == "false" and
- os.environ.get("TRAVIS_BRANCH") == "master"):
+ if (os.environ.get("GITHUB_PULL_REQUEST", "false") == "false" and
+ os.environ.get("GITHUB_BRANCH") == "master"):
# For builds on the master branch just return the HEAD commit
return git("rev-parse", "HEAD")
- elif os.environ.get("TRAVIS_PULL_REQUEST", "false") != "false":
- # This is a PR, so the base branch is in TRAVIS_BRANCH
- travis_branch = os.environ.get("TRAVIS_BRANCH")
- assert travis_branch, "TRAVIS_BRANCH environment variable is defined"
- branch_point = git("merge-base", "HEAD", travis_branch)
+ elif os.environ.get("GITHUB_PULL_REQUEST", "false") != "false":
+ # This is a PR, so the base branch is in GITHUB_BRANCH
+ base_branch = os.environ.get("GITHUB_BRANCH")
+ assert base_branch, "GITHUB_BRANCH environment variable is defined"
+ branch_point = git("merge-base", "HEAD", base_branch)
else:
# Otherwise we aren't on a PR, so we try to find commits that are only in the
# current branch c.f.
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/chromium.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/chromium.py
new file mode 100644
index 00000000000..071c2f37890
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/chromium.py
@@ -0,0 +1,97 @@
+import json
+import time
+
+from collections import defaultdict
+from mozlog.formatters import base
+
+
+class ChromiumFormatter(base.BaseFormatter):
+ """Formatter to produce results matching the Chromium JSON Test Results format.
+ https://chromium.googlesource.com/chromium/src/+/master/docs/testing/json_test_results_format.md
+ """
+
+ def __init__(self):
+ # Whether the run was interrupted, either by the test runner or user.
+ self.interrupted = False
+
+ # A map of test status to the number of tests that had that status.
+ self.num_failures_by_status = defaultdict(int)
+
+ # Start time, expressed as offset since UNIX epoch in seconds.
+ self.start_timestamp_seconds = None
+
+ # Trie of test results. Each directory in the test name is a node in
+ # the trie and the leaf contains the dict of per-test data.
+ self.tests = {}
+
+ def _store_test_result(self, name, actual, expected):
+ """
+ Stores the result of a single test in |self.tests|
+ :param str name: name of the test.
+ :param str actual: actual status of the test.
+ :param str expected: expected status of the test.
+ """
+ # The test name can contain a leading / which will produce an empty
+ # string in the first position of the list returned by split. We use
+ # filter(None) to remove such entries.
+ name_parts = filter(None, name.split("/"))
+ cur_dict = self.tests
+ for name_part in name_parts:
+ cur_dict = cur_dict.setdefault(name_part, {})
+ cur_dict["actual"] = actual
+ cur_dict["expected"] = expected
+
+ def _map_status_name(self, status):
+ """
+ Maps a WPT status to a Chromium status.
+
+ Chromium has five main statuses that we have to map to:
+ CRASH: the test harness crashed
+ FAIL: the test did not run as expected
+ PASS: the test ran as expected
+ SKIP: the test was not run
+ TIMEOUT: the did not finish in time and was aborted
+
+ :param str status: the string status of a test from WPT
+ :return: a corresponding string status for Chromium
+ """
+ if status == "OK":
+ return "PASS"
+ if status == "NOTRUN":
+ return "SKIP"
+ if status == "EXTERNAL-TIMEOUT":
+ return "TIMEOUT"
+ if status in ("ERROR", "CRASH"):
+ # CRASH in WPT means a browser crash, which Chromium treats as a
+ # test failure.
+ return "FAIL"
+ if status == "INTERNAL-ERROR":
+ # CRASH in Chromium refers to an error in the test runner not the
+ # browser.
+ return "CRASH"
+ # Any other status just gets returned as-is.
+ return status
+
+ def suite_start(self, data):
+ self.start_timestamp_seconds = data["time"] if "time" in data else time.time()
+
+ def test_end(self, data):
+ actual_status = self._map_status_name(data["status"])
+ expected_status = self._map_status_name(data["expected"]) if "expected" in data else "PASS"
+ self._store_test_result(data["test"], actual_status, expected_status)
+
+ # Update the count of how many tests ran with each status.
+ self.num_failures_by_status[actual_status] += 1
+
+ def suite_end(self, data):
+ # Create the final result dictionary
+ final_result = {
+ # There are some required fields that we just hard-code.
+ "interrupted": False,
+ "path_delimiter": "/",
+ "version": 3,
+ "seconds_since_epoch": self.start_timestamp_seconds,
+ "num_failures_by_type": self.num_failures_by_status,
+ "tests": self.tests
+ }
+ return json.dumps(final_result)
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py
new file mode 100644
index 00000000000..22d9fb4e7ea
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py
@@ -0,0 +1,118 @@
+import json
+import sys
+from os.path import dirname, join
+from StringIO import StringIO
+
+from mozlog import handlers, structuredlog
+
+sys.path.insert(0, join(dirname(__file__), "..", ".."))
+from formatters import chromium
+
+
+def test_chromium_required_fields(capfd):
+ # Test that the test results contain a handful of required fields.
+
+ # Set up the handler.
+ output = StringIO()
+ logger = structuredlog.StructuredLogger("test_a")
+ logger.add_handler(handlers.StreamHandler(output, chromium.ChromiumFormatter()))
+
+ # output a bunch of stuff
+ logger.suite_start(["test-id-1"], run_info={}, time=123)
+ logger.test_start("test-id-1")
+ logger.test_end("test-id-1", status="PASS", expected="PASS")
+ logger.suite_end()
+
+ # check nothing got output to stdout/stderr
+ # (note that mozlog outputs exceptions during handling to stderr!)
+ captured = capfd.readouterr()
+ assert captured.out == ""
+ assert captured.err == ""
+
+ # check the actual output of the formatter
+ output.seek(0)
+ output_obj = json.load(output)
+
+ # Check for existence of required fields
+ assert "interrupted" in output_obj
+ assert "path_delimiter" in output_obj
+ assert "version" in output_obj
+ assert "num_failures_by_type" in output_obj
+ assert "tests" in output_obj
+
+ test_obj = output_obj["tests"]["test-id-1"]
+ assert "actual" in test_obj
+ assert "expected" in test_obj
+
+def test_chromium_test_name_trie(capfd):
+ # Ensure test names are broken into directories and stored in a trie with
+ # test results at the leaves.
+
+ # Set up the handler.
+ output = StringIO()
+ logger = structuredlog.StructuredLogger("test_a")
+ logger.add_handler(handlers.StreamHandler(output, chromium.ChromiumFormatter()))
+
+ # output a bunch of stuff
+ logger.suite_start(["/foo/bar/test-id-1", "/foo/test-id-2"], run_info={}, time=123)
+ logger.test_start("/foo/bar/test-id-1")
+ logger.test_end("/foo/bar/test-id-1", status="TIMEOUT", expected="FAIL")
+ logger.test_start("/foo/test-id-2")
+ logger.test_end("/foo/test-id-2", status="ERROR", expected="TIMEOUT")
+ logger.suite_end()
+
+ # check nothing got output to stdout/stderr
+ # (note that mozlog outputs exceptions during handling to stderr!)
+ captured = capfd.readouterr()
+ assert captured.out == ""
+ assert captured.err == ""
+
+ # check the actual output of the formatter
+ output.seek(0)
+ output_obj = json.load(output)
+
+ # Ensure that the test names are broken up by directory name and that the
+ # results are stored at the leaves.
+ test_obj = output_obj["tests"]["foo"]["bar"]["test-id-1"]
+ assert test_obj["actual"] == "TIMEOUT"
+ assert test_obj["expected"] == "FAIL"
+
+ test_obj = output_obj["tests"]["foo"]["test-id-2"]
+ # The ERROR status is mapped to FAIL for Chromium
+ assert test_obj["actual"] == "FAIL"
+ assert test_obj["expected"] == "TIMEOUT"
+
+def test_num_failures_by_type(capfd):
+ # Test that the number of failures by status type is correctly calculated.
+
+ # Set up the handler.
+ output = StringIO()
+ logger = structuredlog.StructuredLogger("test_a")
+ logger.add_handler(handlers.StreamHandler(output, chromium.ChromiumFormatter()))
+
+ # Run some tests with different statuses: 3 passes, 1 timeout
+ logger.suite_start(["t1", "t2", "t3", "t4"], run_info={}, time=123)
+ logger.test_start("t1")
+ logger.test_end("t1", status="PASS", expected="PASS")
+ logger.test_start("t2")
+ logger.test_end("t2", status="PASS", expected="PASS")
+ logger.test_start("t3")
+ logger.test_end("t3", status="PASS", expected="FAIL")
+ logger.test_start("t4")
+ logger.test_end("t4", status="TIMEOUT", expected="CRASH")
+ logger.suite_end()
+
+ # check nothing got output to stdout/stderr
+ # (note that mozlog outputs exceptions during handling to stderr!)
+ captured = capfd.readouterr()
+ assert captured.out == ""
+ assert captured.err == ""
+
+ # check the actual output of the formatter
+ output.seek(0)
+ num_failures_by_type = json.load(output)["num_failures_by_type"]
+
+ # We expect 3 passes and 1 timeout, nothing else.
+ assert sorted(num_failures_by_type.keys()) == ["PASS", "TIMEOUT"]
+ assert num_failures_by_type["PASS"] == 3
+ assert num_failures_by_type["TIMEOUT"] == 1
diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py
index eb61461e474..0b5dc82e067 100644
--- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py
+++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptcommandline.py
@@ -8,8 +8,7 @@ from datetime import timedelta
import config
import wpttest
-from formatters import wptreport, wptscreenshot
-
+from formatters import chromium, wptreport, wptscreenshot
def abs_path(path):
return os.path.abspath(os.path.expanduser(path))
@@ -326,6 +325,7 @@ scheme host and port.""")
help="List of URLs for tests to run, or paths including tests to run. "
"(equivalent to --include)")
+ commandline.log_formatters["chromium"] = (chromium.ChromiumFormatter, "Chromium Layout Tests format")
commandline.log_formatters["wptreport"] = (wptreport.WptreportFormatter, "wptreport format")
commandline.log_formatters["wptscreenshot"] = (wptscreenshot.WptscreenshotFormatter, "wpt.fyi screenshots")
diff --git a/tests/wpt/web-platform-tests/webrtc/RTCIceConnectionState-candidate-pair.https.html b/tests/wpt/web-platform-tests/webrtc/RTCIceConnectionState-candidate-pair.https.html
index 7280d040856..6c93aec9260 100644
--- a/tests/wpt/web-platform-tests/webrtc/RTCIceConnectionState-candidate-pair.https.html
+++ b/tests/wpt/web-platform-tests/webrtc/RTCIceConnectionState-candidate-pair.https.html
@@ -19,7 +19,7 @@ promise_test(async t => {
caller.addTrack(track, stream);
exchangeIceCandidates(caller, callee);
await doSignalingHandshake(caller, callee);
- await listenToIceConnected(t, caller);
+ await listenToIceConnected(caller);
const report = await caller.getStats();
let succeededPairFound = false;
diff --git a/tests/wpt/web-platform-tests/webrtc/RTCRtpTransceiver-stop.html b/tests/wpt/web-platform-tests/webrtc/RTCRtpTransceiver-stop.html
index b45e03bd019..4f57dc7b6d3 100644
--- a/tests/wpt/web-platform-tests/webrtc/RTCRtpTransceiver-stop.html
+++ b/tests/wpt/web-platform-tests/webrtc/RTCRtpTransceiver-stop.html
@@ -60,7 +60,7 @@ promise_test(async (t)=> {
const offer = await pc1.createOffer();
assert_true(offer.sdp.includes("a=sendonly"), "The audio m-section should be sendonly");
-}, "A stopped sendonly transceiver should generate an inactive m-section in the offer");
+}, "A stopped sendonly transceiver should generate a sendonly m-section in the offer");
promise_test(async (t)=> {
const pc1 = new RTCPeerConnection();
diff --git a/tests/wpt/web-platform-tests/webrtc/RTCSctpTransport-constructor.html b/tests/wpt/web-platform-tests/webrtc/RTCSctpTransport-constructor.html
index 7d3df051d87..28dae055532 100644
--- a/tests/wpt/web-platform-tests/webrtc/RTCSctpTransport-constructor.html
+++ b/tests/wpt/web-platform-tests/webrtc/RTCSctpTransport-constructor.html
@@ -59,7 +59,7 @@
assert_true(sctp.transport instanceof RTCDtlsTransport,
'Expect sctp.transport to be instance of RTCDtlsTransport');
- assert_true(typeof sctp.maxMessageSize, 'number',
+ assert_true(typeof sctp.maxMessageSize == 'number',
'Expect sctp.maxMessageSize to be a number');
});
}, 'setRemoteDescription() with answer containing data media should initialize pc.sctp');
@@ -82,7 +82,7 @@
assert_true(sctp.transport instanceof RTCDtlsTransport,
'Expect sctp.transport to be instance of RTCDtlsTransport');
- assert_true(typeof sctp.maxMessageSize, 'number',
+ assert_true(typeof sctp.maxMessageSize == 'number',
'Expect sctp.maxMessageSize to be a number');
});
}, 'setLocalDescription() with answer containing data media should initialize pc.sctp');
diff --git a/tests/wpt/web-platform-tests/webrtc/protocol/jsep-initial-offer.https.html b/tests/wpt/web-platform-tests/webrtc/protocol/jsep-initial-offer.https.html
index 88bdfcfc286..50527f88dfe 100644
--- a/tests/wpt/web-platform-tests/webrtc/protocol/jsep-initial-offer.https.html
+++ b/tests/wpt/web-platform-tests/webrtc/protocol/jsep-initial-offer.https.html
@@ -16,19 +16,25 @@
// The first 3 lines are dictated by JSEP.
assert_equals(offer_lines[0], "v=0");
assert_equals(offer_lines[1].slice(0, 2), "o=");
- // JSEP says that the address part SHOULD be a meaningless address
- // "such as" IN IP4 127.0.0.1. We do strict matching here in order
- // to detect if anyone ever uses something different.
- assert_regexp_match(offer_lines[1], /^o=- \d+ \d+ IN IP4 127.0.0.1$/);
- const fields = RegExp(/^o=- (\d+) (\d+)/).exec(offer_lines[1]);
+
+ assert_regexp_match(offer_lines[1], /^o=\S+ \d+ \d+ IN IP4 \S+$/);
+ const fields = RegExp(/^o=\S+ (\d+) (\d+) IN IP4 (\S+)/).exec(offer_lines[1]);
// Per RFC 3264, the sess-id should be representable in an uint64
// Note: JSEP -24 has this wrong - see bug:
// https://github.com/rtcweb-wg/jsep/issues/855
assert_less_than(Number(fields[1]), 2**64);
// Per RFC 3264, the version should be less than 2^62 to avoid overflow
assert_less_than(Number(fields[2]), 2**62);
- // Note: using - in s=- is a SHOULD in JSEP, not a MUST.
- assert_equals(offer_lines[2], "s=-");
+ // JSEP says that the address part SHOULD be a meaningless address
+ // "such as" IN IP4 0.0.0.0. This is to prevent unintentional disclosure
+ // of IP addresses, so this is important enough to verify. Right now we
+ // allow 127.0.0.1 and 0.0.0.0, but there are other things we could allow.
+ // Maybe 0.0.0.0/8, 127.0.0.0/8, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24?
+ // (See RFC 3330, RFC 5737)
+ assert_true(fields[3] == "0.0.0.0" || fields[3] == "127.0.0.1",
+ fields[3] + " must be a meaningless IPV4 address")
+
+ assert_regexp_match(offer_lines[2], /^s=\S+$/);
// After this, the order is not dictated by JSEP.
// TODO: Check lines subsequent to the s= line.
}, 'Offer conforms to basic SDP requirements');
diff --git a/tests/wpt/web-platform-tests/webxr/xrFrame_lifetime.https.html b/tests/wpt/web-platform-tests/webxr/xrFrame_lifetime.https.html
index 971a6d78a1e..30cf5f99677 100644
--- a/tests/wpt/web-platform-tests/webxr/xrFrame_lifetime.https.html
+++ b/tests/wpt/web-platform-tests/webxr/xrFrame_lifetime.https.html
@@ -34,6 +34,7 @@
// Attempting to call a method on the frame outside the callback that
// originally provided it should cause it to throw an exception.
assert_throws('InvalidStateError', () => staleFrame.getViewerPose(currentReferenceSpace));
+ assert_throws('InvalidStateError', () => staleFrame.getPose(testSession.viewerSpace, currentReferenceSpace));
});
// Test does not complete until the this function has executed.
diff --git a/tests/wpt/web-platform-tests/webxr/xrRigidTransform_inverse.https.html b/tests/wpt/web-platform-tests/webxr/xrRigidTransform_inverse.https.html
new file mode 100644
index 00000000000..ddae2af6469
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webxr/xrRigidTransform_inverse.https.html
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https.html b/tests/wpt/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https.html
index 41801bcd364..6c567d2fda6 100644
--- a/tests/wpt/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https.html
+++ b/tests/wpt/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https.html
@@ -32,6 +32,16 @@
let testSession;
+ function checkView(view) {
+ assert_not_equals(view, null);
+ assert_not_equals(view.transform, null);
+
+ let inv_view_transform = view.transform.inverse();
+ assert_not_equals(inv_view_transform, null);
+ assert_not_equals(inv_view_transform.matrix, null);
+ assert_equals(inv_view_transform.matrix.length, 16);
+ }
+
let testFunction = function(session, testDeviceController) {
testSession = session;
return session.requestReferenceSpace({ type: 'stationary', subtype: 'eye-level' })
@@ -49,11 +59,8 @@
assert_not_equals(viewerPose.views, null);
assert_equals(viewerPose.views.length, 2);
-
- assert_not_equals(viewerPose.views[0].viewMatrix, null);
- assert_equals(viewerPose.views[0].viewMatrix.length, 16);
- assert_not_equals(viewerPose.views[1].viewMatrix, null);
- assert_equals(viewerPose.views[1].viewMatrix.length, 16);
+ checkView(viewerPose.views[0]);
+ checkView(viewerPose.views[1]);
// Test does not complete until the returned promise resolves.
resolve();
diff --git a/tests/wpt/web-platform-tests/workers/Worker-custom-event.any.js b/tests/wpt/web-platform-tests/workers/Worker-custom-event.any.js
new file mode 100644
index 00000000000..201e0313b0e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/workers/Worker-custom-event.any.js
@@ -0,0 +1,8 @@
+// META: global=!default,worker
+async_test(t => {
+ var target = self;
+ target.addEventListener('custom-event', t.step_func_done());
+
+ var event = new Event('custom-event');
+ target.dispatchEvent(event);
+}, 'Test CustomEvents on workers.');
diff --git a/tests/wpt/web-platform-tests/workers/Worker-formdata.any.js b/tests/wpt/web-platform-tests/workers/Worker-formdata.any.js
new file mode 100644
index 00000000000..3ee42d9f4b7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/workers/Worker-formdata.any.js
@@ -0,0 +1,19 @@
+// META: global=!default,dedicatedworker
+test(() => {
+ assert_own_property(self, 'FormData');
+ assert_equals(FormData.length, 0);
+
+ var formData = new FormData();
+ assert_not_equals(formData, null);
+ assert_own_property(FormData.prototype, 'append');
+ formData.append('key', 'value');
+
+ var blob = new Blob([]);
+ assert_not_equals(blob, null);
+ formData.append('key', blob);
+ formData.append('key', blob, 'filename');
+
+ assert_throws("DataCloneError",
+ function() { postMessage(formData) },
+ "Trying to clone formdata inside a postMessage results in an exception." );
+},'Test FormData interface object');
diff --git a/tests/wpt/web-platform-tests/workers/Worker-replace-event-handler.any.js b/tests/wpt/web-platform-tests/workers/Worker-replace-event-handler.any.js
new file mode 100644
index 00000000000..1623573c7eb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/workers/Worker-replace-event-handler.any.js
@@ -0,0 +1,11 @@
+// META: global=!default,worker
+// This is a regression test for a crash bug in Chrome: http://crbug.com/239669
+function update() {
+ onmessage = undefined;
+}
+
+test(() => {
+ for (var i = 0; i < 8; ++i) {
+ update();
+ }
+}, "Tests that repeatedly setting 'onmessage' within a worker doesn't crash.");
diff --git a/tests/wpt/web-platform-tests/workers/WorkerNavigator-hardware-concurrency.any.js b/tests/wpt/web-platform-tests/workers/WorkerNavigator-hardware-concurrency.any.js
new file mode 100644
index 00000000000..bd4910fcafa
--- /dev/null
+++ b/tests/wpt/web-platform-tests/workers/WorkerNavigator-hardware-concurrency.any.js
@@ -0,0 +1,4 @@
+// META: global=!default,worker
+test(() => {
+ assert_true(navigator.hardwareConcurrency > 0);
+}, 'Test worker navigator hardware concurrency.');
diff --git a/tests/wpt/web-platform-tests/xhr/FormData-append.html b/tests/wpt/web-platform-tests/xhr/FormData-append.html
index bf6c66d0f66..a10244fa23d 100644
--- a/tests/wpt/web-platform-tests/xhr/FormData-append.html
+++ b/tests/wpt/web-platform-tests/xhr/FormData-append.html
@@ -79,6 +79,14 @@
fd.append('key', 'value1');
assert_equals(fd.get('key'), "null");
}, 'testFormDataAppendToFormNull2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ assert_throws(new TypeError(), () => {fd.append('name', "string", 'filename')});
+ }, 'testFormDataAppendToFormString');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ assert_throws(new TypeError(), () => {fd.append('name', new URLSearchParams(), 'filename')});
+ }, 'testFormDataAppendToFormWrongPlatformObject');
test(function() {
var before = new Date(new Date().getTime() - 2000); // two seconds ago, in case there's clock drift
var fd = create_formdata(['key', new Blob(), 'blank.txt']).get('key');
diff --git a/tests/wpt/web-platform-tests/xhr/formdata-set.htm b/tests/wpt/web-platform-tests/xhr/formdata-set.htm
index f030caa78f9..ee43e1569f1 100644
--- a/tests/wpt/web-platform-tests/xhr/formdata-set.htm
+++ b/tests/wpt/web-platform-tests/xhr/formdata-set.htm
@@ -79,6 +79,14 @@
fd.set('key', 'value1');
assert_equals(fd.get('key'), "value1");
}, 'testFormDataSetToFormNull2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ assert_throws(new TypeError(), () => {fd.set('name', "string", 'filename')});
+ }, 'testFormDataSetToFormString');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ assert_throws(new TypeError(), () => {fd.set('name', new URLSearchParams(), 'filename')});
+ }, 'testFormDataSetToFormWrongPlatformObject');
test(function() {
var fd = new FormData();
fd.set('key', new Blob([]), 'blank.txt');
diff --git a/tests/wpt/web-platform-tests/xhr/formdata.htm b/tests/wpt/web-platform-tests/xhr/formdata.htm
index 65a5d29c671..699c11ab783 100644
--- a/tests/wpt/web-platform-tests/xhr/formdata.htm
+++ b/tests/wpt/web-platform-tests/xhr/formdata.htm
@@ -41,7 +41,7 @@
test(() => {
assert_throws(new TypeError(), () => { new FormData(null); });
assert_throws(new TypeError(), () => { new FormData("string"); });
- }, "Constructors");
+ }, "Constructors should throw a type error");
do_test("empty formdata", new FormData(), '\n');
do_test("formdata with string", create_formdata(['key', 'value']), 'key=value,\n');
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-arraybuffer.any.js b/tests/wpt/web-platform-tests/xhr/send-data-arraybuffer.any.js
new file mode 100644
index 00000000000..71933d08978
--- /dev/null
+++ b/tests/wpt/web-platform-tests/xhr/send-data-arraybuffer.any.js
@@ -0,0 +1,31 @@
+// META: title=XMLHttpRequest.send(arraybuffer)
+
+var test = async_test();
+test.step(function()
+{
+ var xhr = new XMLHttpRequest();
+ var buf = new ArrayBuffer(5);
+ var arr = new Uint8Array(buf);
+ arr[0] = 0x48;
+ arr[1] = 0x65;
+ arr[2] = 0x6c;
+ arr[3] = 0x6c;
+ arr[4] = 0x6f;
+
+ xhr.onreadystatechange = function()
+ {
+ if (xhr.readyState == 4)
+ {
+ test.step(function()
+ {
+ assert_equals(xhr.status, 200);
+ assert_equals(xhr.response, "Hello");
+
+ test.done();
+ });
+ }
+ };
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send(buf);
+});
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-arraybuffer.htm b/tests/wpt/web-platform-tests/xhr/send-data-arraybuffer.htm
deleted file mode 100644
index 25c5d240727..00000000000
--- a/tests/wpt/web-platform-tests/xhr/send-data-arraybuffer.htm
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
- XMLHttpRequest: The send() method: ArrayBuffer data
-
-
-
-
-
-
-
-
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-arraybufferview.any.js b/tests/wpt/web-platform-tests/xhr/send-data-arraybufferview.any.js
new file mode 100644
index 00000000000..a3985b4701d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/xhr/send-data-arraybufferview.any.js
@@ -0,0 +1,18 @@
+// META: title=XMLHttpRequest.send(arraybufferview)
+
+var test = async_test();
+test.step(function()
+{
+ var str = "Hello";
+ var bytes = str.split("").map(function(ch) { return ch.charCodeAt(0); });
+ var xhr = new XMLHttpRequest();
+ var arr = new Uint8Array(bytes);
+
+ xhr.onload = test.step_func_done(function() {
+ assert_equals(xhr.status, 200);
+ assert_equals(xhr.response, str);
+ });
+
+ xhr.open("POST", "./resources/content.py", true);
+ xhr.send(arr);
+});
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-arraybufferview.htm b/tests/wpt/web-platform-tests/xhr/send-data-arraybufferview.htm
deleted file mode 100644
index 4de7e9e8920..00000000000
--- a/tests/wpt/web-platform-tests/xhr/send-data-arraybufferview.htm
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
- XMLHttpRequest: The send() method: ArrayBufferView data
-
-
-
-
-
-
-
-
-
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-es-object.any.js b/tests/wpt/web-platform-tests/xhr/send-data-es-object.any.js
new file mode 100644
index 00000000000..d98a4ca65aa
--- /dev/null
+++ b/tests/wpt/web-platform-tests/xhr/send-data-es-object.any.js
@@ -0,0 +1,50 @@
+// META: title=XMLHttpRequest.send(ES object)
+
+function do_test(obj, expected, name) {
+ var test = async_test(name)
+ test.step(function() {
+ var client = new XMLHttpRequest()
+ client.onload = test.step_func(function () {
+ assert_equals(client.responseText, expected)
+ test.done()
+ });
+ client.open('POST', 'resources/content.py')
+ if (expected.exception) {
+ assert_throws(expected.exception, function(){client.send(obj)})
+ test.done()
+ } else {
+ client.send(obj)
+ }
+ });
+}
+
+do_test({}, '[object Object]', 'sending a plain empty object')
+do_test(Math, '[object Math]', 'sending the ES Math object')
+do_test(new XMLHttpRequest, '[object XMLHttpRequest]', 'sending a new XHR instance')
+do_test({toString:function(){}}, 'undefined', 'sending object that stringifies to undefined')
+do_test({toString:function(){return null}}, 'null', 'sending object that stringifies to null')
+var ancestor = {toString: function(){
+ var ar=[]
+ for (var prop in this) {
+ if (this.hasOwnProperty(prop)) {
+ ar.push(prop+'='+this[prop])
+ }
+ };
+ return ar.join('&')
+}};
+
+var myObj = Object.create(ancestor, {foo:{value:1, enumerable: true}, bar:{value:'foo', enumerable:true}})
+do_test(myObj, 'foo=1&bar=foo', 'object that stringifies to query string')
+
+var myFakeJSON = {a:'a', b:'b', toString:function(){ return JSON.stringify(this, function(key, val){ return key ==='toString'?undefined:val; }) }}
+do_test(myFakeJSON, '{"a":"a","b":"b"}', 'object that stringifies to JSON string')
+
+var myFakeDoc1 = {valueOf:function(){return document}}
+do_test(myFakeDoc1, '[object Object]', 'object whose valueOf() returns a document - ignore valueOf(), stringify')
+
+var myFakeDoc2 = {toString:function(){return document}}
+var expectedError = self.GLOBAL.isWorker() ? new ReferenceError() : new TypeError();
+do_test(myFakeDoc2, {exception:expectedError}, 'object whose toString() returns a document, expected to throw')
+
+var myThrower = {toString:function(){throw {name:'FooError', message:'bar'}}}
+do_test(myThrower, {exception:{name:'FooError'}}, 'object whose toString() throws, expected to throw')
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-es-object.htm b/tests/wpt/web-platform-tests/xhr/send-data-es-object.htm
deleted file mode 100644
index 6f7743286ec..00000000000
--- a/tests/wpt/web-platform-tests/xhr/send-data-es-object.htm
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-XMLHttpRequest: passing objects to send()
-
-
-
-
-
-
-
-
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-formdata.any.js b/tests/wpt/web-platform-tests/xhr/send-data-formdata.any.js
new file mode 100644
index 00000000000..6ff04793ea6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/xhr/send-data-formdata.any.js
@@ -0,0 +1,21 @@
+// META: title=XMLHttpRequest.send(formdata)
+
+var test = async_test();
+test.step(function()
+{
+ var xhr = new XMLHttpRequest();
+ var form = new FormData();
+ form.append("id", "0");
+ form.append("value", "zero");
+
+ xhr.onreadystatechange = test.step_func(() => {
+ if (xhr.readyState == 4) {
+ assert_equals(xhr.status, 200);
+ assert_equals(xhr.response, "id:0;value:zero;");
+ test.done();
+ }
+ });
+
+ xhr.open("POST", "./resources/form.py", true);
+ xhr.send(form);
+});
diff --git a/tests/wpt/web-platform-tests/xhr/send-data-formdata.htm b/tests/wpt/web-platform-tests/xhr/send-data-formdata.htm
deleted file mode 100644
index 9456aa77c53..00000000000
--- a/tests/wpt/web-platform-tests/xhr/send-data-formdata.htm
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
- XMLHttpRequest: The send() method: FormData data
-
-
-
-
-
-
-
-
diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
index 76ff0e820bc..4d0bf200612 100644
--- a/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
+++ b/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
@@ -26,3 +26,6 @@
[WebGL test #100: could not create image (SVG)]
expected: FAIL
+ [WebGL test #116: could not create image (SVG)]
+ expected: FAIL
+