Auto merge of #21629 - servo-wpt-sync:wpt_update_06-09-2018, r=jdm

Sync WPT with upstream (06-09-2018)

Automated downstream sync of changes from upstream as of 06-09-2018.
[no-wpt-sync]

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21629)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-09-06 22:43:25 -04:00 committed by GitHub
commit a9a552e7e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 2084 additions and 260 deletions

View file

@ -109567,6 +109567,18 @@
{}
]
],
"css/css-contain/contain-layout-018.html": [
[
"/css/css-contain/contain-layout-018.html",
[
[
"/css/reference/nothing.html",
"=="
]
],
{}
]
],
"css/css-contain/contain-layout-breaks-001.html": [
[
"/css/css-contain/contain-layout-breaks-001.html",
@ -110011,6 +110023,18 @@
{}
]
],
"css/css-contain/contain-paint-025.html": [
[
"/css/css-contain/contain-paint-025.html",
[
[
"/css/reference/nothing.html",
"=="
]
],
{}
]
],
"css/css-contain/contain-paint-047.html": [
[
"/css/css-contain/contain-paint-047.html",
@ -110551,6 +110575,18 @@
{}
]
],
"css/css-contain/contain-size-grid-002.html": [
[
"/css/css-contain/contain-size-grid-002.html",
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"css/css-contain/contain-size-monolithic-001.html": [
[
"/css/css-contain/contain-size-monolithic-001.html",
@ -110563,6 +110599,18 @@
{}
]
],
"css/css-contain/contain-size-multicol-001.html": [
[
"/css/css-contain/contain-size-multicol-001.html",
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"css/css-contain/contain-size-scrollbars-001.html": [
[
"/css/css-contain/contain-size-scrollbars-001.html",
@ -159899,6 +159947,30 @@
{}
]
],
"css/css-writing-modes/img-intrinsic-size-contribution-001.html": [
[
"/css/css-writing-modes/img-intrinsic-size-contribution-001.html",
[
[
"/css/css-writing-modes/img-intrinsic-size-contribution-ref.html",
"=="
]
],
{}
]
],
"css/css-writing-modes/img-intrinsic-size-contribution-002.html": [
[
"/css/css-writing-modes/img-intrinsic-size-contribution-002.html",
[
[
"/css/css-writing-modes/img-intrinsic-size-contribution-ref.html",
"=="
]
],
{}
]
],
"css/css-writing-modes/inline-block-alignment-002.xht": [
[
"/css/css-writing-modes/inline-block-alignment-002.xht",
@ -185371,6 +185443,18 @@
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html": [
[
"/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html",
[
[
"/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html",
"=="
]
],
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html": [
[
"/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html",
@ -185947,6 +186031,18 @@
{}
]
],
"html/rendering/the-details-element/details-display-property-is-ignored.html": [
[
"/html/rendering/the-details-element/details-display-property-is-ignored.html",
[
[
"/html/rendering/the-details-element/details-display-property-is-ignored-ref.html",
"=="
]
],
{}
]
],
"html/semantics/document-metadata/the-link-element/stylesheet-change-href.html": [
[
"/html/semantics/document-metadata/the-link-element/stylesheet-change-href.html",
@ -198016,6 +198112,11 @@
{}
]
],
"common/slow.py": [
[
{}
]
],
"common/stringifiers.js": [
[
{}
@ -247436,11 +247537,6 @@
{}
]
],
"css/css-contain/support/60x60-red.png": [
[
{}
]
],
"css/css-contain/support/blue-100x100.png": [
[
{}
@ -268226,6 +268322,11 @@
{}
]
],
"css/css-writing-modes/img-intrinsic-size-contribution-ref.html": [
[
{}
]
],
"css/css-writing-modes/inline-block-alignment-002-ref.xht": [
[
{}
@ -269681,6 +269782,11 @@
{}
]
],
"css/css-writing-modes/support/blue-200x100.png": [
[
{}
]
],
"css/css-writing-modes/support/blue-horiz-line-220x1.png": [
[
{}
@ -287921,6 +288027,11 @@
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html": [
[
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html": [
[
{}
@ -288081,6 +288192,11 @@
{}
]
],
"html/rendering/the-details-element/details-display-property-is-ignored-ref.html": [
[
{}
]
],
"html/rendering/the-details-element/single-summary.html": [
[
{}
@ -290506,11 +290622,6 @@
{}
]
],
"html/semantics/scripting-1/the-script-element/resources/slow.py": [
[
{}
]
],
"html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html": [
[
{}
@ -291246,6 +291357,16 @@
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/http-refresh.py": [
[
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/meta-refresh.py": [
[
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/page-with-frame.html": [
[
{}
@ -291256,6 +291377,11 @@
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/slow-png.py": [
[
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/url-frame.html": [
[
{}
@ -292371,6 +292497,11 @@
{}
]
],
"interfaces/trusted-types.tentative.idl": [
[
{}
]
],
"interfaces/uievents.idl": [
[
{}
@ -303456,6 +303587,11 @@
{}
]
],
"tools/ci/tcdownload.py": [
[
{}
]
],
"tools/ci/tests/test_jobs.py": [
[
{}
@ -367426,6 +367562,36 @@
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-immediate.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-immediate.window.html",
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-header.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-header.window.html",
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-meta.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-meta.window.html",
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-while-navigating.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-while-navigating.window.html",
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort.sub.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort.sub.window.html",
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.html",
@ -367540,6 +367706,12 @@
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/mutation-observer.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/mutation-observer.window.html",
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/no-new-global.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/no-new-global.window.html",
@ -396126,6 +396298,12 @@
{}
]
],
"trusted-types/idlharness.window.js": [
[
"/trusted-types/idlharness.window.html",
{}
]
],
"uievents/constructors/inputevent-constructor.html": [
[
"/uievents/constructors/inputevent-constructor.html",
@ -398856,6 +399034,12 @@
{}
]
],
"webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html": [
[
"/webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html",
{}
]
],
"webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html": [
[
"/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html",
@ -427748,7 +427932,7 @@
"support"
],
".taskcluster.yml": [
"70bde33c354105834431f3fb867bc383bd89343f",
"b6d21a17ab5016627041dcd8262573f41c964eaa",
"support"
],
".travis.yml": [
@ -438787,6 +438971,10 @@
"6805c323df5a975231648b830e33ce183c3cbbd3",
"support"
],
"common/slow.py": [
"f3b1c7e2ea61b571bd56cc1c70c5f89bb8e7e4dc",
"support"
],
"common/stringifiers.js": [
"b59ca9c246f75a72d532d58ef628824f8905ff7a",
"support"
@ -461120,11 +461308,11 @@
"testharness"
],
"cookies/prefix/__host.header.html": [
"5a522cbaa018aa607628070ab79278dd855735bd",
"de46485e44c1d349143a9ec7681aea82d1561ee2",
"testharness"
],
"cookies/prefix/__host.header.https.html": [
"53d0dba65989164f5fcb77becd021f264822ebf7",
"a71f75ef41bbcda09ed1dd4a6c666cb51f876fdd",
"testharness"
],
"cookies/prefix/__secure.document-cookie.html": [
@ -461136,11 +461324,11 @@
"testharness"
],
"cookies/prefix/__secure.header.html": [
"431e0e1ec98923feae1f1f6948c7728e5e80b007",
"fb369b62a3bb2e5526a28351813af162a31b4323",
"testharness"
],
"cookies/prefix/__secure.header.https.html": [
"d912babc239acfecef7afb6f7deac9fbfeaf50bd",
"8753a320b4e5925bc2acb88861ee24c4cebe79af",
"testharness"
],
"cookies/prefix/document-cookie.non-secure.html": [
@ -461148,7 +461336,7 @@
"testharness"
],
"cookies/resources/cookie-helper.sub.js": [
"d00a11f6f4396177a9885e30adac435fe8dab479",
"2974da9af069d0fa82779c7c250eb467283f558a",
"support"
],
"cookies/resources/drop.py": [
@ -461196,7 +461384,7 @@
"support"
],
"cookies/resources/set.py": [
"abfb8c8d40d2466759bb423bc8e7fdfc5d72b1fb",
"5b6d0b9a2cc4d233d101441bb10f47418da9b63d",
"support"
],
"cookies/resources/setSameSite.py": [
@ -526487,6 +526675,10 @@
"c8118ad974844cd807e0dfbcc07a9a06469a308c",
"reftest"
],
"css/css-contain/contain-layout-018.html": [
"5d7ebc0195cbbb7bc303784ab05296885c323f40",
"reftest"
],
"css/css-contain/contain-layout-breaks-001.html": [
"a85cf2c6c8e00f1d21fa5a63da81eff8148f3d71",
"reftest"
@ -526635,6 +526827,10 @@
"79ef8a7cc0841ab96b1650cb2e78d210a9432180",
"reftest"
],
"css/css-contain/contain-paint-025.html": [
"0a41b62b2c169d2a5e571bde059a78ad2d5c2a16",
"reftest"
],
"css/css-contain/contain-paint-047.html": [
"e4a0b28457c752232f4314175ffdf1840f7e336a",
"reftest"
@ -526815,10 +527011,18 @@
"f67f0e118e00b3426986b39226310c59b14a3755",
"reftest"
],
"css/css-contain/contain-size-grid-002.html": [
"1e7771e7c12b9c5c879e52071f9f566bd6e2b7d7",
"reftest"
],
"css/css-contain/contain-size-monolithic-001.html": [
"30f19b6cbbd6f6737d5175b1946c17805e0568d6",
"reftest"
],
"css/css-contain/contain-size-multicol-001.html": [
"5c0dba9b7bb56792542decc9abd8fcebd8ab967a",
"reftest"
],
"css/css-contain/contain-size-scrollbars-001.html": [
"304e81e5c98c0ded48c9c498e451dd6c0041566b",
"reftest"
@ -527075,10 +527279,6 @@
"a5b4e9f47a8e60ad0bede1ac81e02b3542c80f3b",
"support"
],
"css/css-contain/support/60x60-red.png": [
"823f125b8e4a60f780f00443c9c9a10b9fa1f447",
"support"
],
"css/css-contain/support/blue-100x100.png": [
"3b72d5ce53c07b68fe508bb57aa61a933dbda768",
"support"
@ -569087,6 +569287,18 @@
"d33fb6f6d119443f41217c2ac1b808cb3eb79b7f",
"reftest"
],
"css/css-writing-modes/img-intrinsic-size-contribution-001.html": [
"08500537f87cdccc1e0736bbaea483b61b690630",
"reftest"
],
"css/css-writing-modes/img-intrinsic-size-contribution-002.html": [
"df0ccf2093bf878200e719cc4f66c70d9832a8a0",
"reftest"
],
"css/css-writing-modes/img-intrinsic-size-contribution-ref.html": [
"ffda7d62ba963ed693e14547adce6592a11f5657",
"support"
],
"css/css-writing-modes/inline-block-alignment-002-ref.xht": [
"ce478e7499247e6277482b9c16c9dd2b1b76f275",
"support"
@ -571511,6 +571723,10 @@
"d325b15a4cf3f12e54adf85c3691de11bebac057",
"support"
],
"css/css-writing-modes/support/blue-200x100.png": [
"e32c47dd1ee8f250025b930a78ce076889af942d",
"support"
],
"css/css-writing-modes/support/blue-horiz-line-220x1.png": [
"3898d5a2d9eb14ad80343ecbcd9d8216d2e2f755",
"support"
@ -586724,7 +586940,7 @@
"support"
],
"docs/_writing-tests/testdriver.md": [
"a934e3278f1e2ea3b105b392cdac0e6a895e1b86",
"eb9b9fb0413862ab41c2064dec88fc10e3f7611a",
"support"
],
"docs/_writing-tests/testharness-api.md": [
@ -603231,6 +603447,14 @@
"f7511c9e4c91dbd2cb11db502789d8792f038a29",
"testharness"
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html": [
"8b1258727fce344978609a1b033389edce7b20be",
"support"
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html": [
"dd1964ba25133850b764c29037fb1113a7c6736f",
"reftest"
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-formatting-context.html": [
"4e9539179739a3690aab276f2ba98c25bd4dfe9b",
"testharness"
@ -603643,6 +603867,14 @@
"3dd95e311aed7fc642e9370dad7cfee5a1eeac1c",
"reftest"
],
"html/rendering/the-details-element/details-display-property-is-ignored-ref.html": [
"6ebed6075de1e8cf62db7bee756b05d3e425e0ab",
"support"
],
"html/rendering/the-details-element/details-display-property-is-ignored.html": [
"445b4e483d00c8aabfa76a946d8cb0871e479c7d",
"reftest"
],
"html/rendering/the-details-element/single-summary.html": [
"1f09e7e75f9126982a07902ae0693f9ea2fd5823",
"support"
@ -609264,11 +609496,11 @@
"testharness"
],
"html/semantics/scripting-1/the-script-element/load-error-events-2.html": [
"cefa053e754335e4a84424422a8bfaa9bc72ba75",
"0748b459092089e12743df4ccb458c6edf770515",
"testharness"
],
"html/semantics/scripting-1/the-script-element/load-error-events-3.html": [
"c2cf0dbdd988507047184bff3489caeb167f6c88",
"83a752ce2cd860ffb4354a540e5b553d720eb4e9",
"testharness"
],
"html/semantics/scripting-1/the-script-element/log.py": [
@ -610135,10 +610367,6 @@
"a6095097dd7e17b1e5370b739b31d361f8fdaf7b",
"support"
],
"html/semantics/scripting-1/the-script-element/resources/slow.py": [
"f3b1c7e2ea61b571bd56cc1c70c5f89bb8e7e4dc",
"support"
],
"html/semantics/scripting-1/the-script-element/script-charset-01.html": [
"c5ac0d0a62a048a55d091935cb6ea733e52a5b82",
"testharness"
@ -610216,7 +610444,7 @@
"testharness"
],
"html/semantics/scripting-1/the-script-element/script-text-modifications.html": [
"7278182e171947bbb546e655de84815ff6cacd83",
"0066d3f4260d92b0f541624062269d13fdbd763d",
"testharness"
],
"html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml": [
@ -612060,13 +612288,33 @@
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/016-1.html": [
"12990a560703a5fec869674b4a12027cb07292cc",
"ceeeb64df63ccb6d56cd46a93c6ec6c476573a6b",
"support"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/016.html": [
"1c70fce591a38dd7917e1fffbd1d9ebab46e8b7f",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-immediate.window.js": [
"8d045b9e0ab56874c5eb32367ed56274e0e94a22",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-header.window.js": [
"8c6c1267c4e899a78bd3ad0e67fd8491fd139606",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-refresh-multisecond-meta.window.js": [
"2895f959e55dc3cf2fdfc933c751699b09438b50",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort-while-navigating.window.js": [
"e3efeffb8b3af56d365336dba357e0d76f7295aa",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/abort.sub.window.js": [
"b2f05cf056d54a0602a55a8dda7c67cb94883055",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js": [
"1d94de8a7c9f28dfab32111deb664d9921437e46",
"testharness"
@ -612147,6 +612395,10 @@
"4efbb863c6372a3ee04d11f38d7ee56a44a2ac7d",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/mutation-observer.window.js": [
"34e73146a9d8e4ecab1e74a0079cd721e7306e59",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/no-new-global.window.js": [
"d4a9296fca66d3017c267a8d8951bef2dcbee238",
"testharness"
@ -612168,7 +612420,7 @@
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/reload.window.js": [
"d6ff9dc7a45425cb688ed4b6c9ea2ab5c1c3ae5c",
"279020f64da8421e118a447bae1373da2e98d9c1",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/aborted-parser-async-frame.html": [
@ -612219,6 +612471,14 @@
"2404105b09a7724cf8cc5e2cf6d7bf7a8fb6f39b",
"support"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/http-refresh.py": [
"d2acd4361f92fe286ab13688a9174ce7c5465755",
"support"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/meta-refresh.py": [
"dd3cef44b44252beb3c7729271c51490a475a660",
"support"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/page-with-frame.html": [
"a1ab01e072b038cd0ec46a8497650845aca83062",
"support"
@ -612227,6 +612487,10 @@
"a92a7ae39f8351f97cd865dca5ebe8d4260aa229",
"support"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/slow-png.py": [
"5fa2fd9a9d850a8a0708985034b89aecf4a51654",
"support"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/url-frame.html": [
"be483ff0aea456c3bc7f2e62d863e7f981453203",
"support"
@ -613791,6 +614055,10 @@
"0bedbf89964f12b55feae4d5e4c9512f71a841cd",
"support"
],
"interfaces/trusted-types.tentative.idl": [
"a3a635b99270381643f16e13ff47facb85cbfb07",
"support"
],
"interfaces/uievents.idl": [
"ba618d7c373bf80c108f4c02996ad0db454f1236",
"support"
@ -624652,7 +624920,7 @@
"testharness"
],
"payment-request/payment-response/onpayerdetailchange-attribute.manual.https.html": [
"9f92d284063fcec7c0ffefb09a076a285cd4b766",
"c8dd92636c6392b2436c8235340355c4529e12c1",
"testharness"
],
"payment-request/payment-response/payerEmail-attribute-manual.https.html": [
@ -644260,7 +644528,7 @@
"support"
],
"tools/ci/check_stability.py": [
"684f7a518940c4ce63fc3360eddb53382f040370",
"2b32eb50c0f62448fed0417d1fe0f7882bf64f14",
"support"
],
"tools/ci/ci_built_diff.sh": [
@ -644276,7 +644544,7 @@
"support"
],
"tools/ci/ci_resources_unittest.sh": [
"78868b93433e801f98782f605eb9f666c6efe9cd",
"a13c60fbd8c0749395a6827babcdf72e97c4fa63",
"support"
],
"tools/ci/ci_stability.sh": [
@ -644284,7 +644552,7 @@
"support"
],
"tools/ci/ci_taskcluster.sh": [
"118243881a938b9d2cae0ebce2662c8ed416eaa4",
"546055293d750a66f713d3942582299a0063492f",
"support"
],
"tools/ci/ci_tools_unittest.sh": [
@ -644300,7 +644568,7 @@
"support"
],
"tools/ci/commands.json": [
"0f8f5823699890e4352016885d2e7fbfc1a9af08",
"361c9e4f3de88b89019481af17875979dc532e5b",
"support"
],
"tools/ci/install.sh": [
@ -644327,6 +644595,10 @@
"f049671c313b18200232f27d1abc75789a2e619d",
"support"
],
"tools/ci/tcdownload.py": [
"8813dccc888881ac8e96a05b22b113d887de0463",
"support"
],
"tools/ci/tests/test_jobs.py": [
"e888ad884a18f257008fe860f31f7892b3bd39a3",
"support"
@ -644344,7 +644616,7 @@
"support"
],
"tools/docker/start.sh": [
"3325bb24f587df72f77c93f01ae447713cd64781",
"c2fd91d96d4dd1a42b72c48e5b477ec5c78174fd",
"support"
],
"tools/flake8.ini": [
@ -649040,7 +649312,7 @@
"support"
],
"tools/wpt/browser.py": [
"9834e5d53f3ab7522f61b12d14aa273ad89ad438",
"65752a25f12864ff70300c2016937d9dd7d7827c",
"support"
],
"tools/wpt/commands.json": [
@ -649048,7 +649320,7 @@
"support"
],
"tools/wpt/install.py": [
"d779651c990e2b7ba798f086e80f6dc8beac525d",
"62c833aa3f0c707e659f691be7a166d8f7ec43d8",
"support"
],
"tools/wpt/markdown.py": [
@ -649064,7 +649336,7 @@
"support"
],
"tools/wpt/run.py": [
"aeeb22be9615e9d2d56b66a8957c997e53babedf",
"036c38f25869bc22f84dfdb67178ccdbcd0bcc7b",
"support"
],
"tools/wpt/testfiles.py": [
@ -649080,7 +649352,7 @@
"support"
],
"tools/wpt/tests/test_wpt.py": [
"b39173e64f23ea4484f75cab219e72e8c2d279d7",
"8f8e5186c7cf508f3ceb5f88a353f85f22f3ad27",
"support"
],
"tools/wpt/tox.ini": [
@ -649628,7 +649900,7 @@
"support"
],
"tools/wptrunner/wptrunner/wptcommandline.py": [
"4af5367a0387c91079aa90dc26a58808f1a936ea",
"e6c624994d91a9c8f70a564d756e01bbcfaef406",
"support"
],
"tools/wptrunner/wptrunner/wptlogging.py": [
@ -649688,11 +649960,11 @@
"support"
],
"tools/wptrunner/wptrunner/wptrunner.py": [
"02420826d8a0bfcb785213150e7e54a291297c05",
"a6a29724ad71794b8e1492d1c1ba792dfdfcacd4",
"support"
],
"tools/wptrunner/wptrunner/wpttest.py": [
"c29ba974a99786f687f2aead1ba14045c12fb643",
"4086a89e4cfd4a246c19722e9a86f7c8a2896af3",
"support"
],
"tools/wptserve/.coveragerc": [
@ -650167,6 +650439,10 @@
"8070b4a4896d9adc60346fccb5fa96b997ef597a",
"testharness"
],
"trusted-types/idlharness.window.js": [
"de13697764ed487060de3dd425cd39cba73ff13b",
"testharness"
],
"trusted-types/support/helper.sub.js": [
"1ad5b4ef0c68a1ffde111db62c5e2aa4957732b6",
"support"
@ -652460,7 +652736,7 @@
"support"
],
"web-animations/animation-model/animation-types/property-types.js": [
"5bafb20dfcfafb34464fe387457f06c434c7c188",
"232a508e07cb3db2eb9d9094a6e9fd8a1e63e4a0",
"support"
],
"web-animations/animation-model/animation-types/visibility.html": [
@ -653831,6 +654107,10 @@
"36bf604b296c63b213d99408ab38937c62a755dc",
"testharness"
],
"webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html": [
"81a1293d0355ed448e60c0e31ad4435ea708e224",
"testharness"
],
"webaudio/the-audio-api/the-pannernode-interface/.gitkeep": [
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
"support"

View file

@ -71,9 +71,3 @@
[bottom intermediate]
expected: FAIL
[line-height end]
expected: FAIL
[border-left-width end]
expected: FAIL

View file

@ -1,4 +1,5 @@
[fetch-in-iframe.html]
expected: CRASH
[Untitled]
expected: FAIL

View file

@ -0,0 +1,4 @@
[traverse_the_history_4.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -0,0 +1,2 @@
[legend-auto-margins.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[details-display-property-is-ignored.html]
expected: FAIL

View file

@ -1,7 +0,0 @@
[016.html]
[Timeout on original window, scope]
expected: FAIL
[Timeout on new window, scope]
expected: FAIL

View file

@ -0,0 +1,14 @@
[abort-refresh-immediate.window.html]
expected: TIMEOUT
[document.open() aborts documents that are queued for navigation through <meta> refresh with timeout 0 (XMLHttpRequest)]
expected: TIMEOUT
[document.open() aborts documents that are queued for navigation through Refresh header with timeout 0 (fetch())]
expected: TIMEOUT
[document.open() aborts documents that are queued for navigation through <meta> refresh with timeout 0 (fetch())]
expected: TIMEOUT
[document.open() aborts documents that are queued for navigation through Refresh header with timeout 0 (XMLHttpRequest)]
expected: TIMEOUT

View file

@ -0,0 +1,11 @@
[abort-refresh-multisecond-header.window.html]
expected: TIMEOUT
[document.open() does NOT abort documents that are queued for navigation through Refresh header with 1-sec timeout (fetch())]
expected: TIMEOUT
[document.open() does NOT abort documents that are queued for navigation through Refresh header with 4-sec timeout (image loading)]
expected: TIMEOUT
[document.open() does NOT abort documents that are queued for navigation through Refresh header with 1-sec timeout (XMLHttpRequest)]
expected: TIMEOUT

View file

@ -0,0 +1,11 @@
[abort-refresh-multisecond-meta.window.html]
expected: TIMEOUT
[document.open() does NOT abort documents that are queued for navigation through <meta> refresh with 4-sec timeout (image loading)]
expected: TIMEOUT
[document.open() does NOT abort documents that are queued for navigation through <meta> refresh with 1-sec timeout (XMLHttpRequest)]
expected: TIMEOUT
[document.open() does NOT abort documents that are queued for navigation through <meta> refresh with 1-sec timeout (fetch())]
expected: TIMEOUT

View file

@ -0,0 +1,17 @@
[abort-while-navigating.window.html]
expected: TIMEOUT
[document.open() aborts documents that are navigating through iframe loading (XMLHttpRequest)]
expected: FAIL
[document.open() aborts documents that are navigating through Location (fetch())]
expected: TIMEOUT
[document.open() aborts documents that are queued for navigation through .click() (fetch())]
expected: TIMEOUT
[document.open() aborts documents that are queued for navigation through .click() (XMLHttpRequest)]
expected: TIMEOUT
[document.open() aborts documents that are navigating through Location (XMLHttpRequest)]
expected: TIMEOUT

View file

@ -0,0 +1,14 @@
[abort.sub.window.html]
expected: TIMEOUT
[document.open() does not abort documents that are not navigating (image loading)]
expected: TIMEOUT
[document.open() does not abort documents that are not navigating (XMLHttpRequest)]
expected: TIMEOUT
[document.open() does not abort documents that are not navigating (establish a WebSocket connection)]
expected: TIMEOUT
[document.open() does not abort documents that are not navigating (fetch())]
expected: TIMEOUT

View file

@ -2,21 +2,15 @@
[request.formData() with input: a&b&c]
expected: FAIL
[response.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[response.formData() with input: a&b&c]
expected: FAIL
[request.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[response.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL
[request.formData() with input: a=b&c=d&]
expected: FAIL
[request.formData() with input: a=b&c=d]
expected: FAIL
[urlencoded-parser.any.worker.html]
[response.formData() with input: a&b&c]
@ -28,15 +22,15 @@
[request.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[response.formData() with input: a=b&c=d]
expected: FAIL
[response.formData() with input: a=b&c=d&]
expected: FAIL
[request.formData() with input: a=b&c=d]
expected: FAIL
[response.formData() with input: &&&a=b&&&&c=d&]
[request.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL
[response.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL

View file

@ -0,0 +1,19 @@
[detune-limiting.html]
[X Osc(freq: 1, detune: 18514.189453125) output does not equal [0,5.565462970480439e-7,0.0000011130925940960879,0.0000016696390048309695,0.0000022261851881921757,0.0000027827315989270573,0.000003339278009661939,0.000003895824193023145,0.000004452370376384351,0.0000050089170144929085,0.000005565463197854115,0.000006122009381215321,0.000006678556019323878,0.000007235102202685084,0.00000779164838604629,0.000008348194569407497...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[1\]\t1.4247585204429924e-4\t5.5654629704804393e-7\t1.4191930574725120e-4\t2.5500000000000000e+2\t0.0000000000000000e+0\n\t[2\]\t2.8495170408859849e-4\t1.1130925940960879e-6\t2.8383861149450240e-4\t2.5500000000000000e+2\t0.0000000000000000e+0\n\t[3\]\t4.2742758523672819e-4\t1.6696390048309695e-6\t4.2575794623189722e-4\t2.5500000000000000e+2\t0.0000000000000000e+0\n\t[4\]\t5.6990334996953607e-4\t2.2261851881921757e-6\t5.6767716478134389e-4\t2.5499997385318113e+2\t0.0000000000000000e+0\n\t[5\]\t7.1237923111766577e-4\t2.7827315989270573e-6\t7.0959649951873871e-4\t2.5499997908254574e+2\t0.0000000000000000e+0\n\t...and 5505 more errors.\n\tMax AbsError of 7.0378831448033452e-1 at index of 5510.\n\t[5510\]\t7.0685487985610962e-1\t3.0665653757750988e-3\t7.0378831448033452e-1\t2.2950376993102469e+2\t0.0000000000000000e+0\n\tMax RelError of 2.5500000000000000e+2 at index of 1.\n]
expected: FAIL
[# AUDIT TASK RUNNER FINISHED: 2 out of 2 tasks were failed.]
expected: FAIL
[X osc[5:\]: Expected 0 for all values but found 5506 unexpected values: \n\tIndex\tActual\n\t[0\]\t0.0007123792311176658\n\t[1\]\t0.0008548550540581346\n\t[2\]\t0.0009973308769986033\n\t[3\]\t0.0011398065835237503\n\t...and 5502 more errors.]
expected: FAIL
[< [detune automation\] 1 out of 3 assertions were failed.]
expected: FAIL
[< [detune limits\] 2 out of 4 assertions were failed.]
expected: FAIL
[X Osc(freq: 44100.00390625) output: Expected 0 for all values but found 5510 unexpected values: \n\tIndex\tActual\n\t[1\]\t5.565462970480439e-7\n\t[2\]\t0.0000011130925940960879\n\t[3\]\t0.0000016696390048309695\n\t[4\]\t0.0000022261851881921757\n\t...and 5506 more errors.]
expected: FAIL

View file

@ -4,71 +4,76 @@ policy:
tasks:
$if: tasks_for == "github-push"
then:
$if: event.ref == "refs/heads/master"
then:
$flattenDeep:
$map: [{name: firefox, channel: nightly}, {name: chrome, channel: dev}]
each(browser):
$map:
- [testharness, 1, 15]
- [testharness, 2, 15]
- [testharness, 3, 15]
- [testharness, 4, 15]
- [testharness, 5, 15]
- [testharness, 6, 15]
- [testharness, 7, 15]
- [testharness, 8, 15]
- [testharness, 9, 15]
- [testharness, 10, 15]
- [testharness, 11, 15]
- [testharness, 12, 15]
- [testharness, 13, 15]
- [testharness, 14, 15]
- [testharness, 15, 15]
- [reftest, 1, 10]
- [reftest, 2, 10]
- [reftest, 3, 10]
- [reftest, 4, 10]
- [reftest, 5, 10]
- [reftest, 6, 10]
- [reftest, 7, 10]
- [reftest, 8, 10]
- [reftest, 9, 10]
- [reftest, 10, 10]
- [wdspec, 1, 1]
each(chunk):
taskId: {$eval: 'as_slugid(browser.name + browser.channel + chunk[0] + str(chunk[1]))'}
taskGroupId: {$eval: 'as_slugid("task group")'}
created: {$fromNow: ''}
deadline: {$fromNow: '24 hours'}
provisionerId: aws-provisioner-v1
# Contributors interested in configurating TaskCluster to run
# against their fork of WPT should change the `workerType` to
# "github-worker".
workerType: wpt-docker-worker
metadata:
name: wpt-${browser.name}-${browser.channel}-${chunk[0]}-${chunk[1]}
description: >-
A subset of WPT's "${chunk[0]}" tests (chunk number ${chunk[1]}
of ${chunk[2]}), run in the ${browser.channel} release of
${browser.name}.
owner: ${event.pusher.email}
source: ${event.repository.url}
payload:
image: gsnedders/web-platform-tests:0.13
maxRunTime: 7200
artifacts:
public/results:
path: /home/test/artifacts
type: directory
command:
- /bin/bash
- --login
- -c
- "~/start.sh ${event.repository.url} ${event.ref[len('refs/heads/'):]} ${event.after} ${browser.name}-${browser.channel} &&
cd ~/web-platform-tests &&
./tools/ci/ci_taskcluster.sh ${browser.name} ${chunk[0]} ${chunk[1]} ${chunk[2]}"
else: []
$flattenDeep:
$map:
$flatten:
$match: {
event.ref == "refs/heads/master": [{name: firefox, channel: nightly}, {name: chrome, channel: dev}],
event.ref == "refs/heads/epochs/daily": [{name: firefox, channel: beta}, {name: chrome, channel: beta}],
event.ref == "refs/heads/epochs/weekly": [{name: firefox, channel: stable}, {name: chrome, channel: stable}]
}
each(browser):
$map:
- [testharness, 1, 15]
- [testharness, 2, 15]
- [testharness, 3, 15]
- [testharness, 4, 15]
- [testharness, 5, 15]
- [testharness, 6, 15]
- [testharness, 7, 15]
- [testharness, 8, 15]
- [testharness, 9, 15]
- [testharness, 10, 15]
- [testharness, 11, 15]
- [testharness, 12, 15]
- [testharness, 13, 15]
- [testharness, 14, 15]
- [testharness, 15, 15]
- [reftest, 1, 10]
- [reftest, 2, 10]
- [reftest, 3, 10]
- [reftest, 4, 10]
- [reftest, 5, 10]
- [reftest, 6, 10]
- [reftest, 7, 10]
- [reftest, 8, 10]
- [reftest, 9, 10]
- [reftest, 10, 10]
- [wdspec, 1, 1]
each(chunk):
taskId: {$eval: 'as_slugid(browser.name + browser.channel + chunk[0] + str(chunk[1]))'}
taskGroupId: {$eval: 'as_slugid("task group")'}
created: {$fromNow: ''}
deadline: {$fromNow: '24 hours'}
provisionerId: aws-provisioner-v1
workerType:
$if: event.repository.full_name == 'web-platform-tests/wpt'
then:
wpt-docker-worker
else:
github-worker
metadata:
name: wpt-${browser.name}-${browser.channel}-${chunk[0]}-${chunk[1]}
description: >-
A subset of WPT's "${chunk[0]}" tests (chunk number ${chunk[1]}
of ${chunk[2]}), run in the ${browser.channel} release of
${browser.name}.
owner: ${event.pusher.email}
source: ${event.repository.url}
payload:
image: harjgam/web-platform-tests:0.14
maxRunTime: 7200
artifacts:
public/results:
path: /home/test/artifacts
type: directory
command:
- /bin/bash
- --login
- -c
- "~/start.sh ${event.repository.url} ${event.ref[len('refs/heads/'):]} ${event.after} ${browser.name} ${browser.channel} &&
cd ~/web-platform-tests &&
./tools/ci/ci_taskcluster.sh ${browser.name} ${browser.channel} ${chunk[0]} ${chunk[1]} ${chunk[2]}"
# > NOTE: A well-designed template should produce `tasks: []` for any
# > unrecognized `task_for` values; this allows later expansion of this
# > service to handle more events.

View file

@ -8,6 +8,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Host-",
params: "Path=/;" + extraParams,
origin: self.origin,
shouldExistInDOM: false,
shouldExistViaHTTP: false,
title: "__Host: Non-secure origin: Does not set 'Path=/;" + extraParams + "'"
@ -17,6 +18,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Host-",
params: "Secure; Path=/;" + extraParams,
origin: self.origin,
shouldExistInDOM: false,
shouldExistViaHTTP: false,
title: "__Host: Non-secure origin: Does not set 'Secure; Path=/;" + extraParams + "'"
@ -26,6 +28,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Host-",
params: "Secure; Path=/; Domain=" + document.location.hostname + "; " + extraParams,
origin: self.origin,
shouldExistInDOM: false,
shouldExistViaHTTP: false,
title: "__Host: Secure origin: Does not set 'Secure; Path=/; Domain=" + document.location.hostname + "; " + extraParams + "'"
@ -35,6 +38,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Host-",
params: "Secure; Path=/cookies/resources/list.py",
origin: self.origin,
shouldExistInDOM: false,
shouldExistViaHTTP: false,
title: "__Host: Non-secure origin: Does not set 'Secure; Path=/cookies/resources/list.py'"

View file

@ -8,6 +8,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Host-",
params: "Path=/;" + extraParams,
origin: self.origin,
shouldExistInDOM: false,
shouldExistViaHTTP: false,
title: "__Host: Secure origin: Does not set 'Path=/;" + extraParams + "'"
@ -17,6 +18,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Host-",
params: "Secure; Path=/;" + extraParams,
origin: self.origin,
shouldExistInDOM: true,
shouldExistViaHTTP: true,
title: "__Host: Secure origin: Does set 'Secure; Path=/;" + extraParams + "'"
@ -26,6 +28,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Host-",
params: "Secure; Path=/; Domain=" + document.location.hostname + "; " + extraParams,
origin: self.origin,
shouldExistInDOM: false,
shouldExistViaHTTP: false,
title: "__Host: Secure origin: Does not set 'Secure; Path=/; Domain=" + document.location.hostname + "; " + extraParams + "'"
@ -35,6 +38,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Host-",
params: "Secure; Path=/cookies/resources/list.py",
origin: self.origin,
shouldExistInDOM: false,
shouldExistViaHTTP: false,
title: "__Host: Secure origin: Does not set 'Secure; Path=/cookies/resources/list.py'"

View file

@ -8,6 +8,7 @@
set_prefixed_cookie_via_http_test({
prefix: "__Secure-",
params: "Path=/;" + extraParams,
origin: self.origin,
shouldExistViaHTTP: false,
title: "__Secure: Non-secure origin: Should not set 'Path=/;" + extraParams + "'"
});
@ -16,8 +17,9 @@
set_prefixed_cookie_via_http_test({
prefix: "__Secure-",
params: "Secure; Path=/;" + extraParams,
shouldExistViaHTTP: true,
title: "__Secure: Non-secure origin: Should set 'Secure; Path=/;" + extraParams + "'"
origin: self.origin,
shouldExistViaHTTP: false,
title: "__Secure: Non-secure origin: Should not set 'Secure; Path=/;" + extraParams + "'"
});
});
</script>

View file

@ -3,11 +3,12 @@
<script src="/resources/testharnessreport.js"></script>
<script src="/cookies/resources/cookie-helper.sub.js"></script>
<script>
["", "domain="+CROSS_SITE_HOST, "MaxAge=10", "HttpOnly"].forEach(extraParams => {
["", "MaxAge=10", "HttpOnly"].forEach(extraParams => {
// Without 'secure'
set_prefixed_cookie_via_http_test({
prefix: "__Secure-",
params: "Path=/;" + extraParams,
origin: self.origin,
shouldExistViaHTTP: false,
title: "__Secure: secure origin: Should not set 'Path=/;" + extraParams + "'"
});
@ -16,8 +17,27 @@
set_prefixed_cookie_via_http_test({
prefix: "__Secure-",
params: "Secure;Path=/;" + extraParams,
origin: self.origin,
shouldExistViaHTTP: true,
title: "__Secure: secure origin: Should set 'Secure;Path=/;" + extraParams + "'"
});
});
// Without 'secure'
set_prefixed_cookie_via_http_test({
prefix: "__Secure-",
params: "Path=/;domain=" + CROSS_SITE_HOST,
origin: SECURE_CROSS_SITE_ORIGIN,
shouldExistViaHTTP: false,
title: "__Secure: secure origin: Should not set 'Path=/;domain=" + CROSS_SITE_HOST + "'"
});
// With 'secure'
set_prefixed_cookie_via_http_test({
prefix: "__Secure-",
params: "Secure;Path=/;domain=" + CROSS_SITE_HOST,
origin: SECURE_CROSS_SITE_ORIGIN,
shouldExistViaHTTP: true,
title: "__Secure: secure origin: Should set 'Secure;Path=/;domain=" + CROSS_SITE_HOST + "'"
});
</script>

View file

@ -28,7 +28,13 @@
// A tiny helper which returns the result of fetching |url| with credentials.
function credFetch(url) {
return fetch(url, {"credentials": "include"});
return fetch(url, {"credentials": "include"})
.then(response => {
if (response.status !== 200) {
throw new Error(response.statusText);
}
return response;
});
}
// Returns a URL on |origin| which redirects to a given absolute URL.
@ -87,23 +93,20 @@ function set_prefixed_cookie_via_dom_test(options) {
function set_prefixed_cookie_via_http_test(options) {
promise_test(t => {
var postDelete = _ => {
var value = "" + Math.random();
return credFetch(options.origin + "/cookies/resources/set.py?" + name + "=" + value + ";" + options.params)
.then(_ => credFetch(options.origin + "/cookies/resources/list.py"))
.then(r => r.json())
.then(cookies => assert_equals(cookies[name], options.shouldExistViaHTTP ? value : undefined));
};
var name = options.prefix + "prefixtestcookie";
if (!options.origin) {
options.origin = self.origin;
erase_cookie_from_js(name, options.params);
return postDelete;
} else {
return credFetch(options.origin + "/cookies/resources/drop.py?name=" + name)
.then(_ => postDelete());
}
var value = "" + Math.random();
t.add_cleanup(() => {
var cookie = name + "=0;expires=" + new Date(0).toUTCString() + ";" +
options.params;
return credFetch(options.origin + "/cookies/resources/set.py?" + cookie);
});
return credFetch(options.origin + "/cookies/resources/set.py?" + name + "=" + value + ";" + options.params)
.then(_ => credFetch(options.origin + "/cookies/resources/list.py"))
.then(r => r.json())
.then(cookies => assert_equals(cookies[name], options.shouldExistViaHTTP ? value : undefined));
}, options.title);
}

View file

@ -1,7 +1,13 @@
import helpers
import urllib
def main(request, response):
"""Respond to `/cookie/set?{cookie}` by echoing `{cookie}` as a `Set-Cookie` header."""
headers = helpers.setNoCacheAndCORSHeaders(request, response)
headers.append(("Set-Cookie", request.url_parts.query))
# Cookies may require whitespace (e.g. in the `Expires` attribute), so the
# query string should be decoded.
cookie = urllib.unquote(request.url_parts.query)
headers.append(("Set-Cookie", cookie))
return headers, '{"success": true}'

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Layout containment stacking context</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
<link rel="match" href="../reference/nothing.html">
<meta name=assert content="Elements in which layout containment doesn't apply, do not create a stacking context.">
<style>
div {
display: inline;
contain: layout;
background: white;
}
span {
position: relative;
z-index: -1;
}
</style>
<p>There should be nothing below.</p>
<div><span>FAIL</span></div>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Paint containment stacking context</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-paint">
<link rel="match" href="../reference/nothing.html">
<meta name=assert content="Elements in which paint containment doesn't apply, do not create a stacking context.">
<style>
div {
display: inline;
contain: paint;
background: white;
}
span {
position: relative;
z-index: -1;
}
</style>
<p>There should be nothing below.</p>
<div><span>FAIL</span></div>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Size containment on grid container with explicit non-intrinsically sized tracks (and gaps)</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
<meta name=assert content="grid-gap, grid-template-columns, and grid-template-rows do affect the size of the grid, even with size containment">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
div {
position: absolute;
}
#red {
background: red;
width: 100px;
height: 100px;
}
#test {
background: green;
contain: size;
display: grid;
grid-gap: 20px;
grid-template-columns: auto 80px; /* 0 + 20 + 80 = 100 */
grid-template-rows: 40px 40px; /* 40 + 20 + 40 = 100 */
font-size: 800px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id=red></div>
<div id=test>&nbsp;</div>
<!--
The &nbsp;, auto sized column, and 800px font size
are to make the test fail in browsers
that do not implement contain:size at all,
by making the box non square.
-->

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Containment Test: Size containment on a multicol with set column size (and gap)</title>
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
<meta name=assert content="columns and column-gap do affect the size of a multicol, even with size containment">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
div {
position: absolute;
}
#red {
background: red;
width: 100px;
height: 100px;
}
#test {
background: green;
columns: 2 40px;
column-gap: 20px;
min-height: 100px;
color: transparent;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id=red></div>
<div id=test>
filler filler filler filler filler filler filler filler
filler filler filler filler filler filler filler filler
filler filler filler filler filler filler filler filler
filler filler filler filler filler filler filler filler
</div>
<!--
The filler text, min-height (instead of height) and transparent color
are to make the test fail in browsers
that do not implement contain:size at all,
by making the box non square.
-->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html style="writing-mode: vertical-lr;">
<title>CSS Test: intrinsic size contributions of images in vertical writing mode</title>
<meta name="assert" content="The image's parent element's intrinsic inline size should be contributed to by the image's height, not the image's width">
<link rel="help" href="http://www.w3.org/TR/css-writing-modes-3/#vertical-layout" title="7.1 Principles of Layout in Vertical Writing Modes">
<link rel="author" title="Zhang Junzhi" href="mailto:zjz@zjz.name">
<link rel="match" href="img-intrinsic-size-contribution-ref.html">
<style>
* { margin: 0; padding: 0; }
</style>
<div style="border: 1px solid blue; display: grid; height: 150px;">
<div style="border: 1px solid orange;">
<img src="support/blue-200x100.png">
</div>
</div>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html style="writing-mode: vertical-lr;">
<title>CSS Test: intrinsic size contributions of images in vertical writing mode (with the image itself in horizontal writing mode)</title>
<meta name="assert" content="The image's parent element's intrinsic inline size should be contributed to by the image's height, not the image's width">
<link rel="help" href="http://www.w3.org/TR/css-writing-modes-3/#vertical-layout" title="7.1 Principles of Layout in Vertical Writing Modes">
<link rel="author" title="Zhang Junzhi" href="mailto:zjz@zjz.name">
<link rel="match" href="img-intrinsic-size-contribution-ref.html">
<style>
* { margin: 0; padding: 0; }
</style>
<div style="border: 1px solid blue; display: grid; height: 150px;">
<div style="border: 1px solid orange;">
<img src="support/blue-200x100.png" style="writing-mode: horizontal-tb;">
</div>
</div>
</html>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<title>CSS Test Reference: intrinsic size contributions of images in vertical writing mode</title>
<link rel="author" title="Zhang Junzhi" href="mailto:zjz@zjz.name">
<style>
* { margin: 0; padding: 0; }
</style>
<div style="border: 1px solid blue; height: 150px; width: 202px;">
<div style="border: 1px solid orange; height: 148px;">
<img src="support/blue-200x100.png">
</div>
</div>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

View file

@ -18,9 +18,11 @@ the global scope.
NB: presently, testdriver.js only works in the top-level test browsing
context (and not therefore in any frame or window opened from it).
### `test_driver.bless(intent, action)`
#### `intent: a string describing the motivation for this invocation`
#### `action: an optional function`
### bless
Usage: `test_driver.bless(intent, action)`
* `intent`: a string describing the motivation for this invocation
* `action`: an optional function
This function simulates [activation][activation], allowing tests to
perform privileged operations that require user interaction. For
@ -44,8 +46,10 @@ test_driver.bless('initiate media playback', function () {
});
```
### `test_driver.click(element)`
#### `element: a DOM Element object`
### click
Usage: `test_driver.click(element)`
* `element`: a DOM Element object
This function causes a click to occur on the target element (an
`Element` object), potentially scrolling the document to make it
@ -57,9 +61,11 @@ Note that if the element to be clicked does not have a unique ID, the
document must not have any DOM mutations made between the function
being called and the promise settling.
### `test_driver.send_keys(element, keys)`
#### `element: a DOM Element object`
#### `keys: string to send to the element`
### send_keys
Usage: `test_driver.send_keys(element, keys)`
* `element`: a DOM Element object
* `keys`: string to send to the element
This function causes the string `keys` to be send to the target
element (an `Element` object), potentially scrolling the document to

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>legend inline auto margins</title>
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1488301">
<style>
body, html { padding:0; margin: 0; }
div {
border: 1px solid black;
border-width: 10px 17px 7px 23px;
padding: 0;
margin: 0;
width: 448px;
height: 5px;
margin-top: 5px;
position: relative;
}
span {
position: absolute;
top: -15px;
width: 200px;
height: 20px;
padding: 0;
margin: 0;
background: grey;
}
center { width: 200px; height: 20px; background: red; }
</style>
</head>
<body>
<div><span style="right:17px"></span></div>
<div><span style="left:31px"></span></div>
<div><span style="left:131px"></span></div>
<div><span style="right:32px"></span></div>
<div><span style="left:46px"></span></div>
</body>
</html>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<title>legend inline auto margins</title>
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1488301">
<link rel="match" href="legend-auto-margins-ref.html">
<style>
body, html { padding:0; margin: 0; }
fieldset {
border: 1px solid black;
border-width: 10px 17px 7px 23px;
padding: 0 17px 0 31px;
margin: 0;
width: 400px;
}
legend {
width: 200px;
height: 20px;
padding: 0;
margin: 0;
background: grey;
}
</style>
</head>
<body>
<fieldset><legend style="margin-left:auto"></legend></fieldset>
<fieldset><legend style="margin-right:auto"></legend></fieldset>
<fieldset><legend style="margin:0 auto"></legend></fieldset>
<fieldset><legend style="margin:0 15px 0 auto"></legend></fieldset>
<fieldset><legend style="margin:0 auto 0 15px"></legend></fieldset>
</body>
</html>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" title="David Grogan" href="dgrogan@chromium.org">
From <a href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">html.spec.whatwg.org</a>:
<blockquote>
The details element is expected to render as a block box. The element's shadow
tree is expected to take the element's first summary element child, if any, and
place it in a first block box container, and then take the element's remaining
descendants, if any, and place them in a second block box container.
</blockquote>
&lt;details display:flex> should be ignored. Otherwise details would render as
something other than a block box.
<hr>
<details open>
<summary>This is the summary.</summary>
<div>thing 1</div>
thing 2
</details>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" title="David Grogan" href="dgrogan@chromium.org">
<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
<link rel="match" href="details-display-property-is-ignored-ref.html">
<link rel="bookmark" href="https://bugs.chromium.org/p/chromium/issues/detail?id=635282" />
<meta name="assert" content="The display property is ignored on details elements and is instead always rendered as a block box." />
From <a href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">html.spec.whatwg.org</a>:
<blockquote>
The details element is expected to render as a block box. The element's shadow
tree is expected to take the element's first summary element child, if any, and
place it in a first block box container, and then take the element's remaining
descendants, if any, and place them in a second block box container.
</blockquote>
&lt;details display:flex> should be ignored. Otherwise details would render as
something other than a block box.
<hr>
<details open style="display:flex;">
<summary>This is the summary.</summary>
<div>thing 1</div>
thing 2
</details>

View file

@ -11,7 +11,7 @@
var test5_load = event_test('no src, parser-inserted, has style sheets blocking scripts, script nesting level == 1', false, false);
</script>
<link rel="stylesheet" href="resources/slow.py"></link>
<link rel="stylesheet" href="/common/slow.py"></link>
<!-- This is testing the case where an inline classic script is inserted
by parser while there is an loading stylesheet. Therefore, it is critical to
place a <link rel="stylesheet"> just above the <script> to be tested. -->

View file

@ -13,7 +13,7 @@ var test6_load = event_test('no src, parser-inserted, has style sheets blocking
false, false);
document.write(
`<link rel="stylesheet" href="resources/slow.py"></link>
`<link rel="stylesheet" href="/common/slow.py"></link>
<script onload="onLoad(test6_load);"
onerror="onError(test6_load);">
"use strict";

View file

@ -12,7 +12,7 @@ var t = async_test("Modify inline script element's text " +
</script>
<!-- This is "a style sheet that is blocking scripts" and thus ... -->
<link rel="stylesheet" href="resources/slow.py"></link>
<link rel="stylesheet" href="/common/slow.py"></link>
<script src="resources/script-text-modifications.py" async></script>

View file

@ -11,7 +11,7 @@ onload = function() {
setTimeout(function() {
parent.tests[0].step(function() {
parent.assert_equals(test_prop, 1, "Global scope from original window timeout");
parent.assert_equals(test_prop, 2, "Global scope from original window timeout");
parent.assert_equals(window.test_prop, 2, "Window property from original window timeout")
});
parent.tests[1].step(function() {
@ -23,7 +23,7 @@ onload = function() {
window.setTimeout(function() {
parent.tests[2].step(function() {
parent.assert_equals(test_prop, 1, "Global scope from original window timeout");
parent.assert_equals(test_prop, 2, "Global scope from original window timeout");
parent.assert_equals(window.test_prop, 2, "Window property from original window timeout")
});
parent.tests[3].step(function() {

View file

@ -0,0 +1,119 @@
// The following tests deal with the <meta http-equiv=refresh> pragma and the
// `Refresh` header. The spec is still hazy on the precise behavior in those
// cases but we use https://github.com/whatwg/html/issues/4003 as a guideline.
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
const client = new frame.contentWindow.XMLHttpRequest();
client.open("GET", "/common/blank.html");
client.onabort = t.step_func_done();
client.send();
frame.contentDocument.open();
});
frame.src = "resources/meta-refresh.py?0";
}, "document.open() aborts documents that are queued for navigation through <meta> refresh with timeout 0 (XMLHttpRequest)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
frame.contentWindow.fetch("/common/blank.html").then(
t.unreached_func("Fetch should have been aborted"),
t.step_func_done());
frame.contentDocument.open();
});
frame.src = "resources/meta-refresh.py?0";
}, "document.open() aborts documents that are queued for navigation through <meta> refresh with timeout 0 (fetch())");
// We cannot test for img element's error event for this test, as Firefox does
// not fire the event if the fetch is aborted while Chrome does.
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const img = frame.contentDocument.createElement("img");
img.src = new URL("resources/slow-png.py", document.URL);
img.onload = t.unreached_func("Image loading should not have succeeded");
// The image fetch starts in a microtask, so let's be sure to test after
// the fetch has started.
t.step_timeout(() => {
frame.contentDocument.open();
happened = true;
});
// If 3 seconds have passed and the image has still not loaded, we consider
// it aborted. slow-png.py only sleeps for 2 wallclock seconds.
t.step_timeout(t.step_func_done(() => {
assert_true(happened);
}), 3000);
});
frame.src = "resources/meta-refresh.py?0";
}, "document.open() aborts documents that are queued for navigation through <meta> refresh with timeout 0 (image loading)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
const client = new frame.contentWindow.XMLHttpRequest();
client.open("GET", "/common/blank.html");
client.onabort = t.step_func_done();
client.send();
frame.contentDocument.open();
});
frame.src = "resources/http-refresh.py?0";
}, "document.open() aborts documents that are queued for navigation through Refresh header with timeout 0 (XMLHttpRequest)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
frame.contentWindow.fetch("/common/blank.html").then(
t.unreached_func("Fetch should have been aborted"),
t.step_func_done());
frame.contentDocument.open();
});
frame.src = "resources/http-refresh.py?0";
}, "document.open() aborts documents that are queued for navigation through Refresh header with timeout 0 (fetch())");
// We cannot test for img element's error event for this test, as Firefox does
// not fire the event if the fetch is aborted while Chrome does.
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const img = frame.contentDocument.createElement("img");
img.src = new URL("resources/slow-png.py", document.URL);
img.onload = t.unreached_func("Image loading should not have succeeded");
// The image fetch starts in a microtask, so let's be sure to test after
// the fetch has started.
t.step_timeout(() => {
frame.contentDocument.open();
happened = true;
});
// If 3 seconds have passed and the image has still not loaded, we consider
// it aborted. slow-png.py only sleeps for 2 wallclock seconds.
t.step_timeout(t.step_func_done(() => {
assert_true(happened);
}), 3000);
});
frame.src = "resources/http-refresh.py?0";
}, "document.open() aborts documents that are queued for navigation through Refresh header with timeout 0 (image loading)");

View file

@ -0,0 +1,69 @@
// The following tests deal with the <meta http-equiv=refresh> pragma and the
// `Refresh` header. The spec is still hazy on the precise behavior in those
// cases but we use https://github.com/whatwg/html/issues/4003 as a guideline.
//
// This is separate from abort-refresh-multisecond-meta.window.js to avoid
// browser interventions that limit the number of connections in a tab.
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const client = new frame.contentWindow.XMLHttpRequest();
client.open("GET", "/common/blank.html");
client.onload = t.step_func_done(() => {
assert_true(happened);
});
client.onerror = t.unreached_func("XMLHttpRequest should have succeeded");
client.onabort = t.unreached_func("XMLHttpRequest should have succeeded");
client.ontimeout = t.unreached_func("XMLHttpRequest should have succeeded");
client.send();
frame.contentDocument.open();
happened = true;
});
frame.src = "resources/http-refresh.py?1";
}, "document.open() does NOT abort documents that are queued for navigation through Refresh header with 1-sec timeout (XMLHttpRequest)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
frame.contentWindow.fetch("/common/blank.html").then(
t.step_func_done(() => {
assert_true(happened);
}),
t.unreached_func("Fetch should have succeeded")
);
frame.contentDocument.open();
happened = true;
});
frame.src = "resources/http-refresh.py?1";
}, "document.open() does NOT abort documents that are queued for navigation through Refresh header with 1-sec timeout (fetch())");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const img = frame.contentDocument.createElement("img");
img.src = new URL("resources/slow-png.py", document.URL);
img.onload = t.step_func_done(() => {
assert_true(happened);
});
img.onerror = t.unreached_func("Image loading should not have errored");
// The image fetch starts in a microtask, so let's be sure to test after
// the fetch has started.
t.step_timeout(() => {
frame.contentDocument.open();
happened = true;
});
});
frame.src = "resources/http-refresh.py?4";
}, "document.open() does NOT abort documents that are queued for navigation through Refresh header with 4-sec timeout (image loading)");

View file

@ -0,0 +1,69 @@
// The following tests deal with the <meta http-equiv=refresh> pragma and the
// `Refresh` header. The spec is still hazy on the precise behavior in those
// cases but we use https://github.com/whatwg/html/issues/4003 as a guideline.
//
// This is separate from abort-refresh-multisecond-header.window.js to avoid
// browser interventions that limit the number of connections in a tab.
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const client = new frame.contentWindow.XMLHttpRequest();
client.open("GET", "/common/blank.html");
client.onload = t.step_func_done(() => {
assert_true(happened);
});
client.onerror = t.unreached_func("XMLHttpRequest should have succeeded");
client.onabort = t.unreached_func("XMLHttpRequest should have succeeded");
client.ontimeout = t.unreached_func("XMLHttpRequest should have succeeded");
client.send();
frame.contentDocument.open();
happened = true;
});
frame.src = "resources/meta-refresh.py?1";
}, "document.open() does NOT abort documents that are queued for navigation through <meta> refresh with 1-sec timeout (XMLHttpRequest)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
frame.contentWindow.fetch("/common/blank.html").then(
t.step_func_done(() => {
assert_true(happened);
}),
t.unreached_func("Fetch should have succeeded")
);
frame.contentDocument.open();
happened = true;
});
frame.src = "resources/meta-refresh.py?1";
}, "document.open() does NOT abort documents that are queued for navigation through <meta> refresh with 1-sec timeout (fetch())");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const img = frame.contentDocument.createElement("img");
img.src = new URL("resources/slow-png.py", document.URL);
img.onload = t.step_func_done(() => {
assert_true(happened);
});
img.onerror = t.unreached_func("Image loading should not have errored");
// The image fetch starts in a microtask, so let's be sure to test after
// the fetch has started.
t.step_timeout(() => {
frame.contentDocument.open();
happened = true;
});
});
frame.src = "resources/meta-refresh.py?4";
}, "document.open() does NOT abort documents that are queued for navigation through <meta> refresh with 4-sec timeout (image loading)");

View file

@ -0,0 +1,179 @@
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
const client = new frame.contentWindow.XMLHttpRequest();
client.open("GET", "/common/blank.html");
// The abort event handler is called synchronously in Chrome but
// asynchronously in Firefox. See https://crbug.com/879620.
client.onabort = t.step_func_done();
client.send();
frame.contentWindow.location.href = new URL("resources/dummy.html", document.URL);
frame.contentDocument.open();
});
frame.src = "/common/blank.html";
}, "document.open() aborts documents that are navigating through Location (XMLHttpRequest)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
frame.contentWindow.fetch("/common/blank.html").then(
t.unreached_func("Fetch should have been aborted"),
t.step_func_done(() => {
assert_true(happened);
}));
frame.contentWindow.location.href = new URL("resources/dummy.html", document.URL);
frame.contentDocument.open();
happened = true;
});
frame.src = "/common/blank.html";
}, "document.open() aborts documents that are navigating through Location (fetch())");
// We cannot test for img element's error event for this test, as Firefox does
// not fire the event if the fetch is aborted while Chrome does.
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const img = frame.contentDocument.createElement("img");
img.src = new URL("resources/slow-png.py", document.URL);
img.onload = t.unreached_func("Image loading should not have succeeded");
// The image fetch starts in a microtask, so let's be sure to test after
// the fetch has started.
t.step_timeout(() => {
frame.contentWindow.location.href = new URL("resources/dummy.html", document.URL);
frame.contentDocument.open();
happened = true;
});
// If 3 seconds have passed and the image has still not loaded, we consider
// it aborted. slow-png.py only sleeps for 2 wallclock seconds.
t.step_timeout(t.step_func_done(() => {
assert_true(happened);
}), 3000);
});
frame.src = "/common/blank.html";
}, "document.open() aborts documents that are navigating through Location (image loading)");
async_test(t => {
const div = document.body.appendChild(document.createElement("div"));
t.add_cleanup(() => div.remove());
div.innerHTML = "<iframe src='/common/slow.py'></iframe>";
const frame = div.childNodes[0];
const client = new frame.contentWindow.XMLHttpRequest();
client.open("GET", "/common/blank.html");
client.onabort = t.step_func_done();
client.send();
frame.contentDocument.open();
}, "document.open() aborts documents that are navigating through iframe loading (XMLHttpRequest)");
async_test(t => {
const div = document.body.appendChild(document.createElement("div"));
t.add_cleanup(() => div.remove());
div.innerHTML = "<iframe src='/common/slow.py'></iframe>";
const frame = div.childNodes[0];
frame.contentWindow.fetch("/common/blank.html").then(
t.unreached_func("Fetch should have been aborted"),
t.step_func_done());
frame.contentDocument.open();
}, "document.open() aborts documents that are navigating through iframe loading (fetch())");
// We cannot test for img element's error event for this test, as Firefox does
// not fire the event if the fetch is aborted while Chrome does.
//
// We use /common/slow.py here as the source of the iframe, to prevent the
// situation where when document.open() is called the initial about:blank
// document has already become inactive.
async_test(t => {
const div = document.body.appendChild(document.createElement("div"));
t.add_cleanup(() => div.remove());
div.innerHTML = "<iframe src='/common/slow.py'></iframe>";
const frame = div.childNodes[0];
let happened = false;
const img = frame.contentDocument.createElement("img");
img.src = new URL("resources/slow-png.py", document.URL);
img.onload = t.unreached_func("Image loading should not have succeeded");
// The image fetch starts in a microtask, so let's be sure to test after
// the fetch has started.
t.step_timeout(() => {
frame.contentDocument.open();
happened = true;
});
// If 3 seconds have passed and the image has still not loaded, we consider
// it aborted. slow-png.py only sleeps for 2 wallclock seconds.
t.step_timeout(t.step_func_done(() => {
assert_true(happened);
}), 3000);
}, "document.open() aborts documents that are navigating through iframe loading (image loading)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
const link = frame.contentDocument.body.appendChild(frame.contentDocument.createElement("a"));
link.href = new URL("resources/dummy.html", document.URL);
const client = new frame.contentWindow.XMLHttpRequest();
client.open("GET", "/common/blank.html");
client.onabort = t.step_func_done();
client.send();
link.click();
frame.contentDocument.open();
});
frame.src = "/common/blank.html";
}, "document.open() aborts documents that are queued for navigation through .click() (XMLHttpRequest)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
const link = frame.contentDocument.body.appendChild(frame.contentDocument.createElement("a"));
link.href = new URL("resources/dummy.html", document.URL);
frame.contentWindow.fetch("/common/blank.html").then(
t.unreached_func("Fetch should have been aborted"),
t.step_func_done());
link.click();
frame.contentDocument.open();
});
frame.src = "/common/blank.html";
}, "document.open() aborts documents that are queued for navigation through .click() (fetch())");
// We cannot test for img element's error event for this test, as Firefox does
// not fire the event if the fetch is aborted while Chrome does.
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
const link = frame.contentDocument.body.appendChild(frame.contentDocument.createElement("a"));
link.href = new URL("resources/dummy.html", document.URL);
let happened = false;
const img = frame.contentDocument.createElement("img");
img.src = new URL("resources/slow-png.py", document.URL);
img.onload = t.unreached_func("Image loading should not have succeeded");
// The image fetch starts in a microtask, so let's be sure to test after
// the fetch has started.
t.step_timeout(() => {
link.click();
frame.contentDocument.open();
happened = true;
});
// If 3 seconds have passed and the image has still not loaded, we consider
// it aborted. slow-png.py only sleeps for 2 wallclock seconds.
t.step_timeout(t.step_func_done(() => {
assert_true(happened);
}), 3000);
});
frame.src = "/common/blank.html";
}, "document.open() aborts documents that are queued for navigation through .click() (image loading)");

View file

@ -0,0 +1,104 @@
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const client = new frame.contentWindow.XMLHttpRequest();
client.open("GET", "/common/blank.html");
client.onload = t.step_func_done(e => {
assert_true(happened);
});
client.onerror = t.unreached_func("XMLHttpRequest should have succeeded");
client.onabort = t.unreached_func("XMLHttpRequest should have succeeded");
client.ontimeout = t.unreached_func("XMLHttpRequest should have succeeded");
client.send();
frame.contentDocument.open();
happened = true;
});
frame.src = "/common/blank.html";
}, "document.open() does not abort documents that are not navigating (XMLHttpRequest)");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
frame.contentWindow.fetch("/common/blank.html").then(
t.step_func_done(() => {
assert_true(happened);
}),
t.unreached_func("Fetch should have succeeded")
);
frame.contentDocument.open();
happened = true;
});
frame.src = "/common/blank.html";
}, "document.open() does not abort documents that are not navigating (fetch())");
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const img = frame.contentDocument.createElement("img");
img.src = new URL("resources/slow-png.py", document.URL);
img.onload = t.step_func_done(() => {
assert_true(happened);
});
img.onerror = t.unreached_func("Image loading should not have errored");
// The image fetch starts in a microtask, so let's be sure to test after
// the fetch has started.
t.step_timeout(() => {
frame.contentDocument.open();
happened = true;
});
});
frame.src = "/common/blank.html";
}, "document.open() does not abort documents that are not navigating (image loading)");
async_test(t => {
const __SERVER__NAME = "{{host}}";
const __PORT = {{ports[ws][0]}};
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const ws = new frame.contentWindow.WebSocket(`ws://${__SERVER__NAME}:${__PORT}/echo`);
ws.onopen = t.step_func_done(() => {
assert_true(happened);
});
ws.onclose = t.unreached_func("WebSocket fetch should have succeeded");
ws.onerror = t.unreached_func("WebSocket should have no error");
frame.contentDocument.open();
happened = true;
});
frame.src = "/common/blank.html";
}, "document.open() does not abort documents that are not navigating (establish a WebSocket connection)");
// An already established WebSocket connection shouldn't be terminated during
// an "abort a document" anyway. Test just for completeness.
async_test(t => {
const __SERVER__NAME = "{{host}}";
const __PORT = {{ports[ws][0]}};
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
frame.onload = t.step_func(() => {
frame.onload = null;
let happened = false;
const ws = new frame.contentWindow.WebSocket(`ws://${__SERVER__NAME}:${__PORT}/echo`);
ws.onopen = t.step_func(() => {
t.step_timeout(t.step_func_done(() => {
assert_true(happened);
}), 100);
frame.contentDocument.open();
happened = true;
});
ws.onclose = t.unreached_func("WebSocket should not be closed");
ws.onerror = t.unreached_func("WebSocket should have no error");
});
frame.src = "/common/blank.html";
}, "document.open() does not abort documents that are not navigating (already established WebSocket connection)");

View file

@ -0,0 +1,19 @@
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => { frame.remove(); });
const originalHTMLElement = frame.contentDocument.documentElement;
assert_equals(originalHTMLElement.localName, "html");
const observer = new frame.contentWindow.MutationObserver(t.step_func_done(records => {
// Even though we passed `subtree: true` to observer.observe, due to the
// fact that "replace all" algorithm removes children with the "suppress
// observers flag" set, we still only get the html element as the sole
// removed node.
assert_equals(records.length, 1);
assert_equals(records[0].type, "childList");
assert_equals(records[0].target, frame.contentDocument);
assert_array_equals(records[0].addedNodes, []);
assert_array_equals(records[0].removedNodes, [originalHTMLElement]);
}));
observer.observe(frame.contentDocument, { childList: true, subtree: true });
assert_equals(frame.contentDocument.open(), frame.contentDocument);
}, "document.open() should inform mutation observer of node removal");

View file

@ -12,16 +12,16 @@
// that restriction.
//
// In any case, this test as the caller of `document.open()` would be used both
// as the test file and as part of the test file. The `if (!opener)` condition
// controls what role this file plays.
// as the test file and as part of the test file. The `if (window.name !==
// "opened-dummy-window")` condition controls what role this file plays.
if (!opener) {
if (window.name !== "opened-dummy-window") {
async_test(t => {
const testURL = document.URL;
const dummyURL = new URL("resources/dummy.html", document.URL).href;
// 1. Open an auxiliary window.
const win = window.open("resources/dummy.html");
const win = window.open("resources/dummy.html", "opened-dummy-window");
t.add_cleanup(() => { win.close(); });
win.addEventListener("load", t.step_func(() => {

View file

@ -0,0 +1,3 @@
def main(request, response):
time = request.url_parts.query if request.url_parts.query else '0'
return 200, [['Refresh', time]], ''

View file

@ -0,0 +1,5 @@
import time
def main(request, response):
time = request.url_parts.query if request.url_parts.query else '0'
return 200, [['Content-Type', 'text/html']], '<meta http-equiv=refresh content=%s>' % time

View file

@ -0,0 +1,8 @@
from base64 import decodestring
import time
png_response = decodestring('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg==')
def main(request, response):
time.sleep(2)
return 200, [], png_response

View file

@ -0,0 +1,53 @@
// https://github.com/wicg/trusted-types
typedef (DOMString or TrustedHTML) HTMLString;
typedef (DOMString or TrustedScript) ScriptString;
typedef (DOMString or TrustedScriptURL) ScriptURLString;
typedef (USVString or TrustedURL) URLString;
[Exposed=Window]
interface TrustedHTML {
stringifier;
};
[Exposed=Window]
interface TrustedScript {
stringifier;
};
[Exposed=Window]
interface TrustedScriptURL {
stringifier;
};
[Exposed=Window]
interface TrustedURL {
stringifier;
};
[Exposed=Window]
interface TrustedTypePolicyFactory {
TrustedTypePolicy createPolicy(DOMString policyName, TrustedTypePolicyOptions policyOptions);
// All the policy object names that have been created
sequence<DOMString> getPolicyNames();
};
[Exposed=Window]
interface TrustedTypePolicy {
readonly attribute DOMString name;
TrustedHTML createHTML(DOMString input);
TrustedScript createScript(DOMString input);
TrustedScriptURL createScriptURL(DOMString input);
TrustedURL createURL(DOMString input);
};
dictionary TrustedTypePolicyOptions {
CreateHTMLCallback createHTML;
CreateScriptCallback createScript;
CreateURLCallback createScriptURL;
CreateURLCallback createURL;
};
callback CreateHTMLCallback = DOMString (DOMString input);
callback CreateScriptCallback = DOMString (DOMString input);
callback CreateURLCallback = USVString (DOMString input);

View file

@ -13,7 +13,7 @@ function runTest(button, options, expected){
response.addEventListener("payerdetailchange", resolve);
});
const error = button.previousElementSibling.textContent.trim();
const retryPromise = response.retry({ error });
await response.retry({ error });
const event = await eventPromise;
assert_true(event instanceof PaymentRequestUpdateEvent);
for(const [prop, value] of Object.entries(expected)){

View file

@ -266,8 +266,7 @@ def run(venv, wpt_args, **kwargs):
do_delayed_imports()
wpt_kwargs["prompt"] = False
wpt_kwargs["install_browser"] = True
wpt_kwargs["install"] = wpt_kwargs["product"].split(":")[0] == "firefox"
wpt_kwargs["install_browser"] = wpt_kwargs["product"].split(":")[0] == "firefox"
wpt_kwargs["pause_after_test"] = False
wpt_kwargs["verify_log_full"] = False

View file

@ -17,7 +17,7 @@ main() {
export PATH=$HOME/firefox:$PATH
cd $WPT_ROOT/resources/test
tox -- --binary=$HOME/browsers/firefox/firefox
tox -- --binary=$HOME/browsers/nightly/firefox/firefox
}
main

View file

@ -3,8 +3,8 @@
./wpt manifest-download
if [ $1 == "firefox" ]; then
./wpt run firefox --log-tbpl=../artifacts/log_tbpl.log --log-tbpl-level=info --log-wptreport=../artifacts/wpt_report.json --log-mach=- --this-chunk=$3 --total-chunks=$4 --test-type=$2 -y --install-browser --no-pause --no-restart-on-unexpected --reftest-internal --install-fonts --no-fail-on-unexpected
./wpt run firefox --log-tbpl=../artifacts/log_tbpl.log --log-tbpl-level=info --log-wptreport=../artifacts/wpt_report.json --log-mach=- --this-chunk=$4 --total-chunks=$5 --test-type=$3 -y --install-browser --channel=$2 --no-pause --no-restart-on-unexpected --reftest-internal --install-fonts --no-fail-on-unexpected
elif [ $1 == "chrome" ]; then
./wpt run chrome --log-tbpl=../artifacts/log_tbpl.log --log-tbpl-level=info --log-wptreport=../artifacts/wpt_report.json --log-mach=- --this-chunk=$3 --total-chunks=$4 --test-type=$2 -y --no-pause --no-restart-on-unexpected --install-fonts --no-fail-on-unexpected
./wpt run chrome --log-tbpl=../artifacts/log_tbpl.log --log-tbpl-level=info --log-wptreport=../artifacts/wpt_report.json --log-mach=- --channel=$2 --this-chunk=$4 --total-chunks=$5 --test-type=$3 -y --no-pause --no-restart-on-unexpected --install-fonts --no-fail-on-unexpected
fi
gzip ../artifacts/wpt_report.json

View file

@ -1,7 +1,42 @@
{
"test-jobs": {"path": "jobs.py", "script": "run", "parser": "create_parser", "help": "List test jobs that should run for a set of commits",
"virtualenv": false},
"check-stability": {"path": "check_stability.py", "script": "run", "parser": "get_parser", "parse_known": true, "help": "Check test stability",
"virtualenv": true, "install": ["requests"], "requirements": ["../wptrunner/requirements.txt"]},
"make-hosts-file": {"path": "make_hosts_file.py", "script": "run", "parser": "create_parser", "help": "Output a hosts file to stdout", "virtualenv": false}
"test-jobs": {
"path": "jobs.py",
"script": "run",
"parser": "create_parser",
"help": "List test jobs that should run for a set of commits",
"virtualenv": false
},
"check-stability": {
"path": "check_stability.py",
"script": "run",
"parser": "get_parser",
"parse_known": true,
"help": "Check test stability",
"virtualenv": true,
"install": [
"requests"
],
"requirements": [
"../wptrunner/requirements.txt"
]
},
"make-hosts-file": {
"path": "make_hosts_file.py",
"script": "run",
"parser": "create_parser",
"help": "Output a hosts file to stdout",
"virtualenv": false
},
"tc-download": {
"path": "tcdownload.py",
"script": "run",
"parser": "get_parser",
"parse_known": true,
"help": "Download logs from taskcluster",
"virtualenv": true,
"install": [
"requests",
"pygithub"
]
}
}

View file

@ -0,0 +1,95 @@
import argparse
import os
import logging
import requests
import github
logging.basicConfig()
logger = logging.getLogger("tc-download")
def get_parser():
parser = argparse.ArgumentParser()
parser.add_argument("--ref", action="store", default="master",
help="Branch (in the GitHub repository) or commit to fetch logs for")
parser.add_argument("--artifact-name", action="store", default="wpt_report.json.gz",
help="Log type to fetch")
parser.add_argument("--repo-name", action="store", default="web-platform-tests/wpt",
help="GitHub repo name in the format owner/repo. "
"This must be the repo from which the TaskCluster run was scheduled "
"(for PRs this is the repo into which the PR would merge)")
parser.add_argument("--token-file", action="store",
help="File containing GitHub token")
parser.add_argument("--out-dir", action="store", default=".",
help="Path to save the logfiles")
return parser
def get_json(url, key=None):
resp = requests.get(url)
resp.raise_for_status()
data = resp.json()
if key:
data = data[key]
return data
def get(url, dest, name):
resp = requests.get(url)
resp.raise_for_status()
path = os.path.join(dest, name)
with open(path, "w") as f:
f.write(resp.content)
return path
def run(*args, **kwargs):
if not os.path.exists(kwargs["out_dir"]):
os.mkdir(kwargs["out_dir"])
if kwargs["token_file"]:
with open(kwargs["token_file"]) as f:
gh = github.Github(f.read().strip())
else:
gh = github.Github()
repo = gh.get_repo(kwargs["repo_name"])
commit = repo.get_commit(kwargs["ref"])
statuses = commit.get_statuses()
taskgroups = set()
for status in statuses:
if not status.context.startswith("Taskcluster "):
continue
if status.state == "pending":
continue
taskgroup_id = status.target_url.rsplit("/", 1)[1]
taskgroups.add(taskgroup_id)
if not taskgroups:
logger.error("No complete TaskCluster runs found for ref %s" % kwargs["ref"])
return
for taskgroup in taskgroups:
taskgroup_url = "https://queue.taskcluster.net/v1/task-group/%s/list"
artifacts_list_url = "https://queue.taskcluster.net/v1/task/%s/artifacts"
tasks = get_json(taskgroup_url % taskgroup, "tasks")
for task in tasks:
task_id = task["status"]["taskId"]
url = artifacts_list_url % (task_id,)
for artifact in get_json(url, "artifacts"):
if artifact["name"].endswith(kwargs["artifact_name"]):
filename = "%s-%s-%s" % (task["task"]["metadata"]["name"],
task_id,
kwargs["artifact_name"])
path = get("%s/%s" % (url, artifact["name"]), kwargs["out_dir"], filename)
logger.info(path)
def __main__():
kwargs = get_parser().parse_args()
run(None, vars(kwargs))

View file

@ -15,6 +15,7 @@ REMOTE=${1:-https://github.com/web-platform-tests/wpt}
BRANCH=${2:-master}
REV=${3:-FETCH_HEAD}
BROWSER=${4:-all}
CHANNEL=${5:-nightly}
cd ~
@ -32,10 +33,22 @@ git checkout -b build ${REV}
sudo sh -c './wpt make-hosts-file >> /etc/hosts'
if [[ $BROWSER == "chrome"* ]] || [[ "$BROWSER" == all ]]
if [[ $BROWSER == "chrome" ]] || [[ "$BROWSER" == all ]]
then
# Install Chrome dev
deb_archive=google-chrome-unstable_current_amd64.deb
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 https://dl.google.com/linux/direct/$deb_archive
sudo apt-get -qqy update && sudo gdebi -n $deb_archive

View file

@ -26,12 +26,12 @@ class Browser(object):
return NotImplemented
@abstractmethod
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
"""Install the WebDriver implementation for this browser."""
return NotImplemented
@abstractmethod
def find_binary(self):
def find_binary(self, venv_path=None, channel=None):
"""Find the binary of the browser.
If the WebDriver for the browser is able to find the binary itself, this
@ -84,9 +84,27 @@ class Firefox(Browser):
return "%s%s" % (platform, bits)
def install(self, dest=None):
def install(self, dest=None, channel="nightly"):
"""Install Firefox."""
branch = {
"nightly": "mozilla-central",
"beta": "mozilla-beta",
"stable": "mozilla-stable"
}
scraper = {
"nightly": "daily",
"beta": "release",
"stable": "release"
}
version = {
"stable": "latest",
"beta": "latest-beta",
"nightly": "latest"
}
if channel not in branch:
raise ValueError("Unrecognised release channel: %s" % channel)
from mozdownload import FactoryScraper
import mozinstall
@ -103,9 +121,12 @@ class Firefox(Browser):
# os.getcwd() doesn't include the venv path
dest = os.path.join(os.getcwd(), "_venv")
dest = os.path.join(dest, "browsers")
dest = os.path.join(dest, "browsers", channel)
filename = FactoryScraper("daily", branch="mozilla-central", destination=dest).download()
filename = FactoryScraper(scraper[channel],
branch=branch[channel],
version=version[channel],
destination=dest).download()
try:
mozinstall.install(filename, dest)
@ -146,11 +167,14 @@ class Firefox(Browser):
return binary
def find_binary(self, venv_path=None):
def find_binary(self, venv_path=None, channel=None):
if venv_path is None:
venv_path = os.path.join(os.getcwd(), "_venv")
binary = self.find_binary_path(os.path.join(venv_path, "browsers"))
path = os.path.join(venv_path, "browsers")
if channel is not None:
path = os.path.join(path, channel)
binary = self.find_binary_path(path)
if not binary and uname[0] == "Darwin":
macpaths = ["/Applications/FirefoxNightly.app/Contents/MacOS",
@ -190,6 +214,18 @@ class Firefox(Browser):
if channel == "stable":
repo = "https://hg.mozilla.org/releases/mozilla-release"
tag = "FIREFOX_%s_RELEASE" % version.replace(".", "_")
elif channel == "beta":
repo = "https://hg.mozilla.org/releases/mozilla-beta"
major_version = version.split(".", 1)[0]
# For beta we have a different format for betas that are now in stable releases
# vs those that are not
tags = get("https://hg.mozilla.org/releases/mozilla-beta/json-tags").json()["tags"]
tags = {item["tag"] for item in tags}
end_tag = "FIREFOX_BETA_%s_END" % major_version
if end_tag in tags:
tag = end_tag
else:
tag = "tip"
else:
repo = "https://hg.mozilla.org/mozilla-central"
if channel == "beta":
@ -202,8 +238,14 @@ class Firefox(Browser):
return "%s/archive/%s.zip/testing/profiles/" % (repo, tag)
def install_prefs(self, binary, dest=None):
version, channel = self.get_version_and_channel(binary)
def install_prefs(self, binary, dest=None, channel=None):
version, channel_ = self.get_version_and_channel(binary)
if channel is not None and channel != channel_:
# Beta doesn't always seem to have the b in the version string, so allow the
# manually supplied value to override the one from the binary
logger.warning("Supplied channel doesn't match binary, using supplied channel")
elif channel is None:
channel = channel_
if dest is None:
dest = os.pwd
@ -257,11 +299,18 @@ 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):
def install_webdriver(self, dest=None, channel=None):
"""Install latest Geckodriver."""
if dest is None:
dest = os.getcwd()
if channel == "nightly":
path = self.install_geckodriver_nightly(dest)
if path is not None:
return path
else:
logger.warning("Nightly webdriver not found; falling back to release")
version = self._latest_geckodriver_version()
format = "zip" if uname[0] == "Windows" else "tar.gz"
logger.debug("Latest geckodriver release %s" % version)
@ -273,9 +322,39 @@ class Firefox(Browser):
untar(get(url).raw, dest=dest)
return find_executable(os.path.join(dest, "geckodriver"))
def version(self, binary=None):
def install_geckodriver_nightly(self, dest):
import tarfile
import mozdownload
logger.info("Attempting to install webdriver from nightly")
try:
s = mozdownload.DailyScraper(branch="mozilla-central",
extension="common.tests.tar.gz",
destination=dest)
package_path = s.download()
except mozdownload.errors.NotFoundError:
return
try:
exe_suffix = ".exe" if uname[0] == "Windows" else ""
with tarfile.open(package_path, "r") as f:
try:
member = f.getmember("bin%sgeckodriver%s" % (os.path.sep,
exe_suffix))
except KeyError:
return
# Remove bin/ from the path.
member.name = os.path.basename(member.name)
f.extractall(members=[member], path=dest)
path = os.path.join(dest, member.name)
logger.info("Extracted geckodriver to %s" % path)
finally:
os.unlink(package_path)
return path
def version(self, binary=None, channel=None):
"""Retrieve the release version of the installed browser."""
binary = binary or self.find_binary()
binary = binary or self.find_binary(channel)
version_string = call(binary, "--version").strip()
m = re.match(r"Mozilla Firefox (.*)", version_string)
if not m:
@ -289,16 +368,16 @@ class Fennec(Browser):
product = "fennec"
requirements = "requirements_firefox.txt"
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def find_binary(self, venv_path=None):
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self):
raise NotImplementedError
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
raise NotImplementedError
def version(self, binary=None):
@ -324,7 +403,7 @@ class Chrome(Browser):
logger.warn("Unable to find the browser binary.")
return None
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def platform_string(self):
@ -346,13 +425,13 @@ class Chrome(Browser):
return "%s%s" % (platform, bits)
def find_binary(self):
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self):
return find_executable("chromedriver")
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
if dest is None:
dest = os.pwd
latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE").text.strip()
@ -391,18 +470,18 @@ class ChromeAndroid(Browser):
product = "chrome_android"
requirements = "requirements_chrome_android.txt"
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def find_binary(self):
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self):
return find_executable("chromedriver")
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
chrome = Chrome()
return chrome.install_webdriver(dest)
return chrome.install_webdriver(dest, channel)
def version(self, binary):
return None
@ -425,7 +504,7 @@ class Opera(Browser):
logger.warn("Unable to find the browser binary.")
return None
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def platform_string(self):
@ -447,13 +526,13 @@ class Opera(Browser):
return "%s%s" % (platform, bits)
def find_binary(self):
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self):
return find_executable("operadriver")
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
if dest is None:
dest = os.pwd
latest = get("https://api.github.com/repos/operasoftware/operachromiumdriver/releases/latest").json()["tag_name"]
@ -487,16 +566,16 @@ class Edge(Browser):
product = "edge"
requirements = "requirements_edge.txt"
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def find_binary(self):
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self):
return find_executable("MicrosoftWebDriver")
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
raise NotImplementedError
def version(self, binary):
@ -509,16 +588,16 @@ class InternetExplorer(Browser):
product = "ie"
requirements = "requirements_ie.txt"
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def find_binary(self):
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self):
return find_executable("IEDriverServer.exe")
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
raise NotImplementedError
def version(self, binary):
@ -534,16 +613,16 @@ class Safari(Browser):
product = "safari"
requirements = "requirements_safari.txt"
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def find_binary(self):
def find_binary(self, venv_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self):
return find_executable("safaridriver")
def install_webdriver(self):
def install_webdriver(self, dest=None, channel=None):
raise NotImplementedError
def version(self, binary):
@ -574,8 +653,10 @@ class Servo(Browser):
return (platform, extension, decompress)
def install(self, dest=None):
def install(self, dest=None, channel="nightly"):
"""Install latest Browser Engine."""
if channel != "nightly":
raise ValueError("Only nightly versions of Servo are available")
if dest is None:
dest = os.pwd
@ -588,13 +669,16 @@ class Servo(Browser):
os.chmod(path, st.st_mode | stat.S_IEXEC)
return path
def find_binary(self):
return find_executable("servo")
def find_binary(self, venv_path=None, channel=None):
path = find_executable("servo", os.path.join(venv_path, "servo"))
if path is None:
path = find_executable("servo")
return path
def find_webdriver(self):
return None
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
raise NotImplementedError
def version(self, binary):
@ -609,16 +693,16 @@ class Sauce(Browser):
product = "sauce"
requirements = "requirements_sauce.txt"
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def find_binary(self):
def find_binary(self, venev_path=None, channel=None):
raise NotImplementedError
def find_webdriver(self):
raise NotImplementedError
def install_webdriver(self, dest=None):
def install_webdriver(self, dest=None, channel=None):
raise NotImplementedError
def version(self, binary):
@ -631,16 +715,16 @@ class WebKit(Browser):
product = "webkit"
requirements = "requirements_webkit.txt"
def install(self, dest=None):
def install(self, dest=None, channel=None):
raise NotImplementedError
def find_binary(self, path=None):
def find_binary(self, venv_path=None, channel=None):
return None
def find_webdriver(self):
return None
def install_webdriver(self):
def install_webdriver(self, dest=None, channel=None):
raise NotImplementedError
def version(self, binary):

View file

@ -2,20 +2,62 @@ import argparse
import browser
import sys
latest_channels = {
'firefox': 'nightly',
'chrome': 'dev',
'servo': 'nightly'
}
channel_by_name = {
'stable': 'stable',
'release': 'stable',
'beta': 'beta',
'nightly': latest_channels,
'dev': latest_channels,
'preview': latest_channels,
'experimental': latest_channels,
}
def get_parser():
parser = argparse.ArgumentParser()
parser.add_argument('browser', choices=['firefox', 'chrome'],
parser = argparse.ArgumentParser(description="""Install a given browser or webdriver frontend.
For convenience the release channel of the browser accepts various spellings,
but we actually support at most three variants; whatever the latest development
release is (e.g. Firefox nightly or Chrome dev), the latest beta release, and
the most recent stable release.""")
parser.add_argument('browser', choices=['firefox', 'chrome', 'servo'],
help='name of web browser product')
parser.add_argument('component', choices=['browser', 'webdriver'],
help='name of component')
parser.add_argument('--channel', choices=channel_by_name.keys(),
default="nightly", help='Name of browser release channel. '
'"stable" and "release" are synonyms for the latest browser stable release,'
'"nightly", "dev", "experimental", and "preview" are all synonyms for '
'the latest available development release. For WebDriver installs, '
'we attempt to select an appropriate, compatible, version for the '
'latest browser release on the selected channel.')
parser.add_argument('-d', '--destination',
help='filesystem directory to place the component')
return parser
def get_channel(browser, channel):
channel = channel_by_name[channel]
if isinstance(channel, dict):
channel = channel[browser]
return channel
def run(venv, **kwargs):
browser = kwargs["browser"]
destination = kwargs["destination"]
channel = get_channel(browser, kwargs["channel"])
if channel != kwargs["channel"]:
print "Interpreting channel '%s' as '%s'" % (kwargs["channel"],
channel)
if destination is None:
if venv:
@ -27,10 +69,10 @@ def run(venv, **kwargs):
raise argparse.ArgumentError(None,
"No --destination argument, and no default for the environment")
install(browser, kwargs["component"], destination)
install(browser, kwargs["component"], destination, channel)
def install(name, component, destination):
def install(name, component, destination, channel="nightly"):
if component == 'webdriver':
method = 'install_webdriver'
else:
@ -38,4 +80,6 @@ def install(name, component, destination):
subclass = getattr(browser, name.title())
sys.stdout.write('Now installing %s %s...\n' % (name, component))
getattr(subclass(), method)(dest=destination)
path = getattr(subclass(), method)(dest=destination, channel=channel)
if path:
sys.stdout.write('Binary installed as %s\n' % (path,))

View file

@ -7,7 +7,7 @@ from distutils.spawn import find_executable
wpt_root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
sys.path.insert(0, os.path.abspath(os.path.join(wpt_root, "tools")))
from . import browser, utils, virtualenv
from . import browser, install, utils, virtualenv
from ..serve import serve
logger = None
@ -47,7 +47,15 @@ def create_parser():
parser.add_argument("--yes", "-y", dest="prompt", action="store_false", default=True,
help="Don't prompt before installing components")
parser.add_argument("--install-browser", action="store_true",
help="Install the latest development version of the browser")
help="Install the browser")
parser.add_argument("--channel", action="store",
choices=install.channel_by_name.keys(),
default=None, help='Name of browser release channel.'
'"stable" and "release" are synonyms for the latest browser stable release,'
'"nightly", "dev", "experimental", and "preview" are all synonyms for '
'the latest available development release. For WebDriver installs, '
'we attempt to select an appropriate, compatible, version for the '
'latest browser release on the selected channel.')
parser._add_container_actions(wptcommandline.create_parser())
return parser
@ -150,9 +158,9 @@ class BrowserSetup(object):
elif resp == "n":
return False
def install(self, venv):
def install(self, venv, channel=None):
if self.prompt_install(self.name):
return self.browser.install(venv.path)
return self.browser.install(venv.path, channel)
def install_requirements(self):
self.venv.install_requirements(os.path.join(wpt_root, "tools", "wptrunner", self.browser.requirements))
@ -167,7 +175,8 @@ class Firefox(BrowserSetup):
def setup_kwargs(self, kwargs):
if kwargs["binary"] is None:
binary = self.browser.find_binary(self.venv.path)
binary = self.browser.find_binary(self.venv.path,
kwargs["browser_channel"])
if binary is None:
raise WptrunError("""Firefox binary not found on $PATH.
@ -205,7 +214,9 @@ Consider installing certutil via your OS package manager or directly.""")
kwargs["test_types"].remove("wdspec")
if kwargs["prefs_root"] is None:
prefs_root = self.browser.install_prefs(kwargs["binary"], self.venv.path)
prefs_root = self.browser.install_prefs(kwargs["binary"],
self.venv.path,
channel=kwargs["browser_channel"])
kwargs["prefs_root"] = prefs_root
@ -290,7 +301,7 @@ class Edge(BrowserSetup):
name = "edge"
browser_cls = browser.Edge
def install(self, venv):
def install(self, venv, channel=None):
raise NotImplementedError
def setup_kwargs(self, kwargs):
@ -311,7 +322,7 @@ class InternetExplorer(BrowserSetup):
name = "ie"
browser_cls = browser.InternetExplorer
def install(self, venv):
def install(self, venv, channel=None):
raise NotImplementedError
def setup_kwargs(self, kwargs):
@ -332,7 +343,7 @@ class Safari(BrowserSetup):
name = "safari"
browser_cls = browser.Safari
def install(self, venv):
def install(self, venv, channel=None):
raise NotImplementedError
def setup_kwargs(self, kwargs):
@ -349,7 +360,7 @@ class Sauce(BrowserSetup):
name = "sauce"
browser_cls = browser.Sauce
def install(self, venv):
def install(self, venv, channel=None):
raise NotImplementedError
def setup_kwargs(self, kwargs):
@ -362,13 +373,13 @@ class Servo(BrowserSetup):
name = "servo"
browser_cls = browser.Servo
def install(self, venv):
def install(self, venv, channel=None):
if self.prompt_install(self.name):
return self.browser.install(venv.path)
def setup_kwargs(self, kwargs):
if kwargs["binary"] is None:
binary = self.browser.find_binary()
binary = self.browser.find_binary(self.venv.path, None)
if binary is None:
raise WptrunError("Unable to find servo binary on the PATH")
@ -379,7 +390,7 @@ class WebKit(BrowserSetup):
name = "webkit"
browser_cls = browser.WebKit
def install(self, venv):
def install(self, venv, channel=None):
raise NotImplementedError
def setup_kwargs(self, kwargs):
@ -401,7 +412,7 @@ product_setup = {
}
def setup_wptrunner(venv, prompt=True, install=False, **kwargs):
def setup_wptrunner(venv, prompt=True, install_browser=False, **kwargs):
from wptrunner import wptrunner, wptcommandline
global logger
@ -424,9 +435,20 @@ def setup_wptrunner(venv, prompt=True, install=False, **kwargs):
setup_cls = product_setup[kwargs["product"]](venv, prompt, sub_product)
setup_cls.install_requirements()
if install:
if install_browser and not kwargs["channel"]:
kwargs["channel"] = "nightly"
if kwargs["channel"]:
channel = install.get_channel(kwargs["product"], kwargs["channel"])
if channel != kwargs["channel"]:
logger.info("Interpreting channel '%s' as '%s'" % (kwargs["channel"],
channel))
kwargs["browser_channel"] = channel
del kwargs["channel"]
if install_browser:
logger.info("Installing browser")
kwargs["binary"] = setup_cls.install(venv)
kwargs["binary"] = setup_cls.install(venv, channel=channel)
setup_cls.setup(kwargs)
@ -447,7 +469,7 @@ def run(venv, **kwargs):
kwargs = setup_wptrunner(venv,
prompt=prompt,
install=install_browser,
install_browser=install_browser,
**kwargs)
rv = run_single(venv, **kwargs) > 0

View file

@ -166,9 +166,9 @@ def test_run_firefox(manifest_dir):
os.environ["MOZ_HEADLESS"] = "1"
try:
if sys.platform == "darwin":
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "Firefox Nightly.app")
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "Firefox Nightly.app")
else:
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "firefox")
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "firefox")
if os.path.exists(fx_path):
shutil.rmtree(fx_path)
with pytest.raises(SystemExit) as excinfo:
@ -294,15 +294,14 @@ def test_install_chromedriver():
@pytest.mark.xfail(sys.platform == "win32",
reason="Tests currently don't work on Windows for path reasons")
def test_install_firefox():
if sys.platform == "darwin":
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "Firefox Nightly.app")
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "Firefox Nightly.app")
else:
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "firefox")
fx_path = os.path.join(wpt.localpaths.repo_root, "_venv", "browsers", "nightly", "firefox")
if os.path.exists(fx_path):
shutil.rmtree(fx_path)
with pytest.raises(SystemExit) as excinfo:
wpt.main(argv=["install", "firefox", "browser"])
wpt.main(argv=["install", "firefox", "browser", "--channel=nightly"])
assert excinfo.value.code == 0
assert os.path.exists(fx_path)
shutil.rmtree(fx_path)

View file

@ -192,6 +192,12 @@ scheme host and port.""")
help="Path to directory containing extra json files to add to run info")
config_group.add_argument("--product", action="store", choices=product_choices,
default=None, help="Browser against which to run tests")
config_group.add_argument("--browser-version", action="store",
default=None, help="Informative string detailing the browser "
"release version. This is included in the run_info data.")
config_group.add_argument("--browser-channel", action="store",
default=None, help="Informative string detailing the browser "
"release channel. This is included in the run_info data.")
config_group.add_argument("--config", action="store", type=abs_path, dest="config",
help="Path to config file")
config_group.add_argument("--install-fonts", action="store_true",

View file

@ -47,6 +47,7 @@ def get_loader(test_paths, product, debug=None, run_info_extras=None, **kwargs):
run_info = wpttest.get_run_info(kwargs["run_info"], product,
browser_version=kwargs.get("browser_version"),
browser_channel=kwargs.get("browser_channel"),
debug=debug,
extras=run_info_extras)

View file

@ -67,7 +67,10 @@ def get_run_info(metadata_root, product, **kwargs):
class RunInfo(dict):
def __init__(self, metadata_root, product, debug, browser_version=None, extras=None):
def __init__(self, metadata_root, product, debug,
browser_version=None,
browser_channel=None,
extras=None):
import mozinfo
self._update_mozinfo(metadata_root)
self.update(mozinfo.info)
@ -89,6 +92,8 @@ class RunInfo(dict):
self["debug"] = False
if browser_version:
self["browser_version"] = browser_version
if browser_channel:
self["browser_channel"] = browser_channel
if extras is not None:
self.update(extras)

View file

@ -0,0 +1,18 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
idl_test(
['trusted-types.tentative'],
['dom', 'html'],
idl_array => {
idl_array.add_objects({
TrustedTypePolicyFactory: ['window.TrustedTypes'],
TrustedTypePolicy: ['window.TrustedTypes.createPolicy("SomeName", { createHTML: s => s })'],
TrustedHTML: ['window.TrustedTypes.createPolicy("SomeName1", { createHTML: s => s }).createHTML("A string")'],
TrustedScript: ['window.TrustedTypes.createPolicy("SomeName2", { createScript: s => s }).createScript("A string")'],
TrustedScriptURL: ['window.TrustedTypes.createPolicy("SomeName3", { createScriptURL: s => s }).createScriptURL("A string")'],
TrustedURL: ['window.TrustedTypes.createPolicy("SomeName4", { createURL: s => s }).createURL("A string")']
});
},
'Trusted Types'
);

View file

@ -1068,6 +1068,23 @@ const transformListType = {
{ time: 500, expected: [ 1, 1, 1, 1, 100, 100 ] },
{ time: 1000, expected: [ 1, 1, 1, 1, 100, 100 ] }]);
}, `${property}: non-invertible matrices in mismatched transform lists`);
test(t => {
const idlName = propertyToIDL(property);
const target = createTestElement(t, setup);
const animation = target.animate(
{
[idlName]: ['perspective(0)', 'perspective(10px)'],
},
1000
);
testAnimationSampleMatrices(animation, idlName,
[{ time: 500, expected: [ 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, -0.05,
0, 0, 0, 1 ] }]);
}, `${property}: perspective`);
},
testAddition: function(property, setup) {

View file

@ -0,0 +1,154 @@
<!doctype html>
<html>
<head>
<title>
Oscillator Detune Limits
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webaudio/resources/audit.js"></script>
</head>
<body>
<script>
const sampleRate = 44100;
const renderLengthSeconds = 0.125;
let audit = Audit.createTaskRunner();
audit.define(
{
label: 'detune limits',
description:
'Oscillator with detune and frequency at Nyquist or above'
},
(task, should) => {
let context = new OfflineAudioContext(
2, renderLengthSeconds * sampleRate, sampleRate);
let merger = new ChannelMergerNode(
context, {numberOfInputs: context.destination.channelCount});
merger.connect(context.destination);
// For test oscillator, set the oscillator frequency to -Nyquist and
// set detune to be a large number that would cause the detuned
// frequency to be way above Nyquist.
const oscFrequency = 1;
const detunedFrequency = sampleRate;
const detuneValue = Math.fround(1200 * Math.log2(detunedFrequency));
let testOsc = new OscillatorNode(
context, {frequency: oscFrequency, detune: detuneValue});
testOsc.connect(merger, 0, 1);
// For the reference oscillator, determine the computed oscillator
// frequency using the values above and set that as the oscillator
// frequency.
let computedFreq = oscFrequency * Math.pow(2, detuneValue / 1200);
let refOsc = new OscillatorNode(context, {frequency: computedFreq});
refOsc.connect(merger, 0, 0);
// Start 'em up and render
testOsc.start();
refOsc.start();
context.startRendering()
.then(renderedBuffer => {
let expected = renderedBuffer.getChannelData(0);
let actual = renderedBuffer.getChannelData(1);
// Let user know about the smaple rate so following messages
// make more sense.
should(context.sampleRate, 'Context sample rate')
.beEqualTo(context.sampleRate);
// Since the frequency is at Nyquist, the reference oscillator
// output should be zero.
should(
refOsc.frequency.value, 'Reference oscillator frequency')
.beGreaterThanOrEqualTo(context.sampleRate / 2);
should(
expected, `Osc(freq: ${refOsc.frequency.value}) output`)
.beConstantValueOf(0);
// The output from each oscillator should be the same.
should(
actual,
'Osc(freq: ' + oscFrequency + ', detune: ' + detuneValue +
') output')
.beCloseToArray(expected, {absoluteThreshold: 0});
})
.then(() => task.done());
});
audit.define(
{
label: 'detune automation',
description:
'Oscillator output with detune automation should be zero ' +
'above Nyquist'
},
(task, should) => {
let context = new OfflineAudioContext(
1, renderLengthSeconds * sampleRate, sampleRate);
const baseFrequency = 1;
const rampEnd = renderLengthSeconds / 2;
const detuneEnd = 1e7;
let src = new OscillatorNode(context, {frequency: baseFrequency});
src.detune.linearRampToValueAtTime(detuneEnd, rampEnd);
src.connect(context.destination);
src.start();
context.startRendering()
.then(renderedBuffer => {
let audio = renderedBuffer.getChannelData(0);
// At some point, the computed oscillator frequency will go
// above Nyquist. Determine at what time this occurrs. The
// computed frequency is f * 2^(d/1200) where |f| is the
// oscillator frequency and |d| is the detune value. Thus,
// find |d| such that Nyquist = f*2^(d/1200). That is, d =
// 1200*log2(Nyquist/f)
let criticalDetune =
1200 * Math.log2(context.sampleRate / 2 / baseFrequency);
// Now figure out at what point on the linear ramp does the
// detune value reach this critical value. For a linear ramp:
//
// v(t) = V0+(V1-V0)*(t-T0)/(T1-T0)
//
// Thus,
//
// t = ((T1-T0)*v(t) + T0*V1 - T1*V0)/(V1-V0)
//
// In this test, T0 = 0, V0 = 0, T1 = rampEnd, V1 =
// detuneEnd, and v(t) = criticalDetune
let criticalTime = (rampEnd * criticalDetune) / detuneEnd;
let criticalFrame =
Math.ceil(criticalTime * context.sampleRate);
should(
criticalFrame,
`Frame where detuned oscillator reaches Nyquist`)
.beEqualTo(criticalFrame);
should(
audio.slice(0, criticalFrame),
`osc[0:${criticalFrame - 1}]`)
.notBeConstantValueOf(0);
should(audio.slice(criticalFrame), `osc[${criticalFrame}:]`)
.beConstantValueOf(0);
})
.then(() => task.done());
});
audit.run();
</script>
</body>
</html>