Auto merge of #27401 - servo-wpt-sync:wpt_update_25-07-2020, r=servo-wpt-sync

Sync WPT with upstream (25-07-2020)

Automated downstream sync of changes from upstream as of 25-07-2020.
[no-wpt-sync]
r? @servo-wpt-sync
This commit is contained in:
bors-servo 2020-07-25 06:33:29 -04:00 committed by GitHub
commit fa9b077e84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
85 changed files with 697 additions and 264 deletions

View file

@ -1,4 +0,0 @@
[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-004.html]
[Miss float below something else]
expected: FAIL

View file

@ -0,0 +1,4 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -11,33 +11,6 @@
[[data-expected-height\] 2] [[data-expected-height\] 2]
expected: FAIL expected: FAIL
[[data-expected-height\] 1] [[data-expected-height\] 4]
expected: FAIL
[[data-expected-height\] 10]
expected: FAIL
[[data-expected-height\] 2]
expected: FAIL
[[data-expected-height\] 5]
expected: FAIL
[[data-expected-height\] 6]
expected: FAIL
[[data-expected-height\] 9]
expected: FAIL
[[data-expected-height\] 8]
expected: FAIL
[[data-expected-height\] 13]
expected: FAIL
[[data-expected-height\] 12]
expected: FAIL
[[data-expected-height\] 11]
expected: FAIL expected: FAIL

View file

@ -2,3 +2,6 @@
[Hit test intersecting scaled box] [Hit test intersecting scaled box]
expected: FAIL expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

@ -0,0 +1,4 @@
[CaretPosition-001.html]
[Element at (400, 100)]
expected: FAIL

View file

@ -2,3 +2,6 @@
[listeners are called when <iframe> is resized] [listeners are called when <iframe> is resized]
expected: FAIL expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -1,4 +0,0 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -2,3 +2,6 @@
[elementsFromPoint on the root document for points in iframe elements] [elementsFromPoint on the root document for points in iframe elements]
expected: FAIL expected: FAIL
[elementsFromPoint on inner documents]
expected: FAIL

View file

@ -315,15 +315,6 @@
[<iframe>: separate response Content-Type: text/html */*] [<iframe>: separate response Content-Type: text/html */*]
expected: FAIL expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk] [<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL expected: FAIL
@ -336,6 +327,6 @@
[<iframe>: separate response Content-Type: text/html;" \\" text/plain] [<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain] [<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL expected: FAIL

View file

@ -53,6 +53,3 @@
[combined text/javascript ] [combined text/javascript ]
expected: FAIL expected: FAIL
[separate text/javascript x/x]
expected: FAIL

View file

@ -11,3 +11,9 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!] [X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL expected: FAIL
[X-Content-Type-Options%3A%20%22nosniFF%22]
expected: FAIL
[X-Content-Type-Options%3A%20%40%23%24%23%25%25%26%5E%26%5E*()()11!%2Cnosniff]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_1.html]
[Multiple history traversals from the same task]
expected: FAIL

View file

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

View file

@ -1,2 +0,0 @@
[cross-origin-objects-on-new-window.html]
expected: TIMEOUT

View file

@ -1,8 +1,7 @@
[embedded-opener-remove-frame.html] [embedded-opener-remove-frame.html]
expected: CRASH
[opener of discarded nested browsing context] [opener of discarded nested browsing context]
expected: FAIL expected: FAIL
[opener of discarded auxiliary browsing context] [opener of discarded auxiliary browsing context]
expected: TIMEOUT expected: FAIL

View file

@ -1,16 +1,20 @@
[supported-elements.html] [supported-elements.html]
expected: TIMEOUT
[Contenteditable element should support autofocus] [Contenteditable element should support autofocus]
expected: FAIL expected: TIMEOUT
[Host element with delegatesFocus including no focusable descendants should be skipped] [Host element with delegatesFocus including no focusable descendants should be skipped]
expected: FAIL expected: NOTRUN
[Element with tabindex should support autofocus] [Element with tabindex should support autofocus]
expected: FAIL expected: NOTRUN
[Area element should support autofocus] [Area element should support autofocus]
expected: FAIL expected: NOTRUN
[Host element with delegatesFocus should support autofocus] [Host element with delegatesFocus should support autofocus]
expected: FAIL expected: NOTRUN
[Non-HTMLElement should not support autofocus]
expected: NOTRUN

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-2.html] [iframe_sandbox_popups_escaping-2.html]
expected: CRASH expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: TIMEOUT

View file

@ -1,5 +1,4 @@
[iframe_sandbox_popups_escaping-3.html] [iframe_sandbox_popups_escaping-3.html]
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: FAIL

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_nonescaping-2.html] [iframe_sandbox_popups_nonescaping-2.html]
expected: TIMEOUT expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN expected: NOTRUN

View file

@ -1,5 +1,4 @@
[iframe_sandbox_popups_nonescaping-3.html] [iframe_sandbox_popups_nonescaping-3.html]
expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL expected: FAIL

View file

@ -1,4 +0,0 @@
[module-static-import-delayed.html]
[document.write in an imported module]
expected: FAIL

View file

@ -1,5 +1,5 @@
[ignore-opens-during-unload.window.html] [ignore-opens-during-unload.window.html]
expected: TIMEOUT expected: CRASH
[document.open should bail out when ignore-opens-during-unload is greater than 0 during visibilitychange event (open(parent) while unloading parent and child)] [document.open should bail out when ignore-opens-during-unload is greater than 0 during visibilitychange event (open(parent) while unloading parent and child)]
expected: TIMEOUT expected: TIMEOUT

View file

@ -1,10 +1,9 @@
[promise-job-entry.html] [promise-job-entry.html]
expected: TIMEOUT
[Fulfillment handler on fulfilled promise] [Fulfillment handler on fulfilled promise]
expected: FAIL expected: FAIL
[Rejection handler on pending-then-rejected promise] [Rejection handler on pending-then-rejected promise]
expected: TIMEOUT expected: FAIL
[Sanity check: this all works as expected with no promises involved] [Sanity check: this all works as expected with no promises involved]
expected: FAIL expected: FAIL
@ -16,5 +15,5 @@
expected: FAIL expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise] [Fulfillment handler on pending-then-fulfilled promise]
expected: TIMEOUT expected: FAIL

View file

@ -0,0 +1,8 @@
[promise-rejection-events.html]
expected: TIMEOUT
[delayed handling: delaying handling rejected promise created from createImageBitmap will cause both events to fire]
expected: TIMEOUT
[unhandledrejection: from createImageBitmap which is UA triggered]
expected: FAIL

View file

@ -1,2 +1,4 @@
[resource_initiator_types.html] [resource_initiator_types.html]
expected: TIMEOUT [Testing resource entries]
expected: FAIL

View file

@ -1,5 +0,0 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -0,0 +1,2 @@
[Worker-constructor.html]
expected: ERROR

View file

@ -1,5 +1,4 @@
[003.html] [003.html]
expected: ERROR
[shared] [shared]
expected: FAIL expected: FAIL

View file

@ -162101,6 +162101,32 @@
{} {}
] ]
], ],
"active-selection-031.html": [
"387bb82082f3a13cd5867aefa33b44d836d18eb8",
[
null,
[
[
"/css/css-pseudo/reference/active-selection-031-ref.html",
"=="
]
],
{}
]
],
"active-selection-045.html": [
"415aa60610a85327362f3a4e592168ab9fccbbe3",
[
null,
[
[
"/css/reference/ref-nothing-below.xht",
"=="
]
],
{}
]
],
"active-selection-051.html": [ "active-selection-051.html": [
"caab01e392428560331729292f99b91bd20ac20e", "caab01e392428560331729292f99b91bd20ac20e",
[ [
@ -247708,7 +247734,7 @@
[] []
], ],
".taskcluster.yml": [ ".taskcluster.yml": [
"47a243a855db0ff3ed9f191170f02762e44392e1", "526fc13212e9b2ac9abfb54fcdcddea63a63c80a",
[] []
], ],
".well-known": { ".well-known": {
@ -305969,6 +305995,10 @@
"active-selection-024-ref.html": [ "active-selection-024-ref.html": [
"e6dda1c1371b53e12f9a6601eea67ac4f5604a3b", "e6dda1c1371b53e12f9a6601eea67ac4f5604a3b",
[] []
],
"active-selection-031-ref.html": [
"0e3680844f887050520d8fb9b9bd2f68a2234e85",
[]
] ]
}, },
"selection-text-shadow-016-ref.html": [ "selection-text-shadow-016-ref.html": [
@ -305979,6 +306009,12 @@
"1e068262780074b3f2acb50ae8cee69b84c72af3", "1e068262780074b3f2acb50ae8cee69b84c72af3",
[] []
], ],
"support": {
"100x100-red.png": [
"57bf3ddc5213d06e0975de38f330ffb7c441b268",
[]
]
},
"textpath-selection-011-ref.html": [ "textpath-selection-011-ref.html": [
"d9ba940518e121eeb0e9701ccd4e36772fdfa786", "d9ba940518e121eeb0e9701ccd4e36772fdfa786",
[] []
@ -345563,7 +345599,7 @@
[] []
], ],
"testdriver.js": [ "testdriver.js": [
"a8588b44f94c78f0a3c2542385bce20cfd1a64c9", "4d373c9281d85e6ff37a6d0dfe4cdc2fc9c10787",
[] []
], ],
"testdriver.js.headers": [ "testdriver.js.headers": [
@ -348613,7 +348649,13 @@
"helpers.js": [ "helpers.js": [
"c8c40646481a055cd1b7abf693e8f45cab769fba", "c8c40646481a055cd1b7abf693e8f45cab769fba",
[] []
] ],
"resources": {
"set-cookie.py": [
"019697a4a8608943e0258664138ce9a7b6ae6876",
[]
]
}
}, },
"streams": { "streams": {
"META.yml": [ "META.yml": [
@ -349905,7 +349947,7 @@
[] []
], ],
"decision.py": [ "decision.py": [
"070ae5f1903b6dbf56f535990611c04b89690bdf", "0820a6798b5b233581eb561a973cb97ff2af44e1",
[] []
], ],
"download.py": [ "download.py": [
@ -349922,7 +349964,7 @@
], ],
"tasks": { "tasks": {
"test.yml": [ "test.yml": [
"9e8e689d8163368abfb0bc7bef776581643d29d7", "dd14fc71b915e90f0625dc1120aed3c86a787e53",
[] []
] ]
}, },
@ -349984,7 +350026,7 @@
[] []
], ],
"Dockerfile": [ "Dockerfile": [
"6b49393bc872adc021333d6578bca41f3481ebc1", "d8b64c2585f9998ecec4db2ca9adb97f650167b1",
[] []
], ],
"README.md": [ "README.md": [
@ -355687,7 +355729,7 @@
} }
}, },
"tox.ini": [ "tox.ini": [
"45358c081efbb00d528d6d176b93d28dd081b8cb", "1a94ec340216417584bc54bf3527d90920993789",
[] []
], ],
"wave": { "wave": {
@ -356306,7 +356348,7 @@
[] []
], ],
"browser.py": [ "browser.py": [
"cb5974078a8022d30402a5dac8137470e8fd1ecc", "85b7b63c21972614208bda68979fd8b974535e97",
[] []
], ],
"commands.json": [ "commands.json": [
@ -356318,7 +356360,7 @@
[] []
], ],
"install.py": [ "install.py": [
"1fe091879b5ca04c16e9c965380b97025ec74521", "81770225428d4605b142e18914ce142f7724b1cd",
[] []
], ],
"mach-emulator.manifest": [ "mach-emulator.manifest": [
@ -356342,7 +356384,7 @@
[] []
], ],
"run.py": [ "run.py": [
"32f903ce9bd64474aa387ac03a7bcb36d47bb8ae", "79329a5dab4472d73fefeaf9b0d48057dc40eba1",
[] []
], ],
"testfiles.py": [ "testfiles.py": [
@ -356375,12 +356417,12 @@
[] []
], ],
"test_wpt.py": [ "test_wpt.py": [
"f897b688ad6f682be9d769da98579c788505c09a", "d2d0b541a3796528929522ef62c2e80cb7e8735c",
[] []
] ]
}, },
"tox.ini": [ "tox.ini": [
"8e3e26e135b4d376a492aea5adbd242797b03fe0", "7e6eb8e42a4c7b248988ef1984a0583961e08105",
[] []
], ],
"update.py": [ "update.py": [
@ -356388,7 +356430,7 @@
[] []
], ],
"utils.py": [ "utils.py": [
"18551481ab8cae42a6707156922619df3fa59b48", "6608af754b2adaf77610552f0db4ee67e4b4e621",
[] []
], ],
"virtualenv.py": [ "virtualenv.py": [
@ -356634,7 +356676,7 @@
} }
}, },
"tox.ini": [ "tox.ini": [
"c544da7a95d2a982cab8b68af537440b71fa096b", "798f64a3e422e4da0b4e4b6fe15d686b20af572e",
[] []
], ],
"wptrunner": { "wptrunner": {
@ -485259,7 +485301,7 @@
] ]
], ],
"payment-request-hasenrolledinstrument-method.tentative.https.html": [ "payment-request-hasenrolledinstrument-method.tentative.https.html": [
"c55312ce33b0da2fcd1d1619b6d7ff8c614a4f6b", "4f6b7e9239b67e4317c325af651ab685f0c63c44",
[ [
null, null,
{ {
@ -485324,7 +485366,7 @@
] ]
], ],
"payment-request-show-method.https.html": [ "payment-request-show-method.https.html": [
"dcf78ef4281c4256ecb4141b3f93d15a947805a3", "20d5bab0d14b79fb3dcf3e82e08dc495d038a33d",
[ [
null, null,
{ {
@ -504577,6 +504619,15 @@
"storage-access-api/sandboxAttribute.window.html", "storage-access-api/sandboxAttribute.window.html",
{} {}
] ]
],
"storageAccess.testdriver.sub.html": [
"59f925f4bf503ce1cdacbe9cf17b9c10406790e4",
[
null,
{
"testdriver": true
}
]
] ]
}, },
"streams": { "streams": {
@ -505592,7 +505643,7 @@
] ]
], ],
"then-interception.any.js": [ "then-interception.any.js": [
"848bb5affd87080077c2729d91943e283f3e0c8e", "9f772ea5841d8f35487e7fa978bdd187b89896cd",
[ [
null, null,
{ {
@ -507699,7 +507750,7 @@
] ]
], ],
"patched-global.any.js": [ "patched-global.any.js": [
"bf353bc241ffab12c558912851940785bcdf62f2", "416edf815c3867511ee16057624307c3e9a3fa5c",
[ [
null, null,
{ {

View file

@ -1,4 +0,0 @@
[hit-test-floats-003.html]
[Miss float below something else]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-004.html]
[Miss float below something else]
expected: FAIL

View file

@ -0,0 +1,4 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -8,9 +8,6 @@
[[data-expected-height\] 3] [[data-expected-height\] 3]
expected: FAIL expected: FAIL
[[data-expected-height\] 1] [[data-expected-height\] 4]
expected: FAIL
[[data-expected-height\] 2]
expected: FAIL expected: FAIL

View file

@ -2,3 +2,6 @@
[Hit test intersecting scaled box] [Hit test intersecting scaled box]
expected: FAIL expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

@ -0,0 +1,4 @@
[CaretPosition-001.html]
[Element at (400, 100)]
expected: FAIL

View file

@ -2,3 +2,6 @@
[listeners are called when <iframe> is resized] [listeners are called when <iframe> is resized]
expected: FAIL expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -1,4 +0,0 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -2,3 +2,6 @@
[elementsFromPoint on the root document for points in iframe elements] [elementsFromPoint on the root document for points in iframe elements]
expected: FAIL expected: FAIL
[elementsFromPoint on inner documents]
expected: FAIL

View file

@ -315,15 +315,6 @@
[<iframe>: separate response Content-Type: text/html */*] [<iframe>: separate response Content-Type: text/html */*]
expected: FAIL expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk] [<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL expected: FAIL
@ -336,6 +327,6 @@
[<iframe>: separate response Content-Type: text/html;" \\" text/plain] [<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain] [<iframe>: combined response Content-Type: text/html;" \\" text/plain]
expected: FAIL expected: FAIL

View file

@ -53,6 +53,3 @@
[combined text/javascript ] [combined text/javascript ]
expected: FAIL expected: FAIL
[separate text/javascript x/x]
expected: FAIL

View file

@ -11,3 +11,9 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!] [X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL expected: FAIL
[X-Content-Type-Options%3A%20%22nosniFF%22]
expected: FAIL
[X-Content-Type-Options%3A%20%40%23%24%23%25%25%26%5E%26%5E*()()11!%2Cnosniff]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_1.html]
[Multiple history traversals from the same task]
expected: FAIL

View file

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

View file

@ -1,2 +0,0 @@
[cross-origin-objects-on-new-window.html]
expected: TIMEOUT

View file

@ -1,5 +1,4 @@
[embedded-opener-remove-frame.html] [embedded-opener-remove-frame.html]
expected: CRASH
[opener and "removed" embedded documents] [opener and "removed" embedded documents]
expected: FAIL expected: FAIL
@ -7,5 +6,5 @@
expected: FAIL expected: FAIL
[opener of discarded auxiliary browsing context] [opener of discarded auxiliary browsing context]
expected: TIMEOUT expected: FAIL

View file

@ -1,16 +1,20 @@
[supported-elements.html] [supported-elements.html]
expected: TIMEOUT
[Contenteditable element should support autofocus] [Contenteditable element should support autofocus]
expected: FAIL expected: TIMEOUT
[Element with tabindex should support autofocus] [Element with tabindex should support autofocus]
expected: FAIL expected: NOTRUN
[Host element with delegatesFocus including no focusable descendants should be skipped] [Host element with delegatesFocus including no focusable descendants should be skipped]
expected: FAIL expected: NOTRUN
[Area element should support autofocus] [Area element should support autofocus]
expected: FAIL expected: NOTRUN
[Host element with delegatesFocus should support autofocus] [Host element with delegatesFocus should support autofocus]
expected: FAIL expected: NOTRUN
[Non-HTMLElement should not support autofocus]
expected: NOTRUN

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-2.html] [iframe_sandbox_popups_escaping-2.html]
expected: CRASH expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: TIMEOUT

View file

@ -1,6 +1,5 @@
[iframe_sandbox_popups_escaping-3.html] [iframe_sandbox_popups_escaping-3.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: FAIL

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_nonescaping-2.html] [iframe_sandbox_popups_nonescaping-2.html]
type: testharness type: testharness
expected: TIMEOUT expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN expected: NOTRUN

View file

@ -1,6 +1,5 @@
[iframe_sandbox_popups_nonescaping-3.html] [iframe_sandbox_popups_nonescaping-3.html]
type: testharness type: testharness
expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: FAIL expected: FAIL

View file

@ -9,3 +9,9 @@
[Check that rel=noopener with target=_top does a normal load] [Check that rel=noopener with target=_top does a normal load]
expected: FAIL expected: FAIL
[Check that rel=noopener with target=_self does a normal load]
expected: FAIL
[Check that rel=noopener with target=_parent does a normal load]
expected: FAIL

View file

@ -1,4 +0,0 @@
[module-static-import-delayed.html]
[document.write in an imported module]
expected: FAIL

View file

@ -1,5 +1,5 @@
[ignore-opens-during-unload.window.html] [ignore-opens-during-unload.window.html]
expected: TIMEOUT expected: CRASH
[ignore-opens-during-unload] [ignore-opens-during-unload]
expected: FAIL expected: FAIL

View file

@ -1,10 +1,9 @@
[promise-job-entry.html] [promise-job-entry.html]
expected: TIMEOUT
[Fulfillment handler on fulfilled promise] [Fulfillment handler on fulfilled promise]
expected: FAIL expected: FAIL
[Rejection handler on pending-then-rejected promise] [Rejection handler on pending-then-rejected promise]
expected: TIMEOUT expected: FAIL
[Sanity check: this all works as expected with no promises involved] [Sanity check: this all works as expected with no promises involved]
expected: FAIL expected: FAIL
@ -16,5 +15,5 @@
expected: FAIL expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise] [Fulfillment handler on pending-then-fulfilled promise]
expected: TIMEOUT expected: FAIL

View file

@ -1,6 +1,7 @@
[promise-rejection-events.html] [promise-rejection-events.html]
expected: TIMEOUT
[delayed handling: delaying handling rejected promise created from createImageBitmap will cause both events to fire] [delayed handling: delaying handling rejected promise created from createImageBitmap will cause both events to fire]
expected: FAIL expected: TIMEOUT
[unhandledrejection: from createImageBitmap which is UA triggered] [unhandledrejection: from createImageBitmap which is UA triggered]
expected: FAIL expected: FAIL

View file

@ -1,5 +1,4 @@
[resource_initiator_types.html] [resource_initiator_types.html]
expected: TIMEOUT
[http://web-platform.test:8000/resource-timing/resources/all_resource_types.htm is not expected to be in the Resource Timing buffer] [http://web-platform.test:8000/resource-timing/resources/all_resource_types.htm is not expected to be in the Resource Timing buffer]
expected: FAIL expected: FAIL

View file

@ -1,5 +0,0 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -0,0 +1,2 @@
[Worker-constructor.html]
expected: ERROR

View file

@ -1,6 +1,5 @@
[003.html] [003.html]
type: testharness type: testharness
expected: ERROR
[shared] [shared]
expected: FAIL expected: FAIL

View file

@ -57,7 +57,7 @@ tasks:
owner: ${owner} owner: ${owner}
source: ${event.repository.clone_url} source: ${event.repository.clone_url}
payload: payload:
image: webplatformtests/wpt:0.42 image: webplatformtests/wpt:0.46
maxRunTime: 7200 maxRunTime: 7200
artifacts: artifacts:
public/results: public/results:

View file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Pseudo-Elements Test: active selection and vertical writing-modes</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://www.w3.org/TR/css-pseudo-4/#highlight-styling">
<link rel="match" href="reference/active-selection-031-ref.html">
<meta content="" name="flags">
<style>
div > div
{
color: red;
float: left;
font-size: 48px;
margin-left: 16px;
}
div.vrl
{
writing-mode: vertical-rl;
}
div.vlr
{
writing-mode: vertical-lr;
}
div.mixed
{
text-orientation: mixed;
}
div.sideways
{
text-orientation: sideways;
}
div.upright
{
text-orientation: upright;
}
div::selection
{
background-color: yellow;
color: green;
}
</style>
<script>
function startTest()
{
var targetRange = document.createRange();
/* We first create an empty range */
targetRange.selectNodeContents(document.getElementById("test"));
/* Then we set the range boundaries to the contents of div#test */
window.getSelection().addRange(targetRange);
/* Finally, we now add such range of content into a selection */
}
</script>
<body onload="startTest();">
<p>Test passes if each glyph of the 6 "Selected Text" is green and if there is <strong>no red</strong>.
<div id="test">
<div class="vrl mixed">Selected Text</div>
<div class="vrl sideways">Selected Text</div>
<div class="vrl upright">Selected Text</div>
<div class="vlr mixed">Selected Text</div>
<div class="vlr sideways">Selected Text</div>
<div class="vlr upright">Selected Text</div>
</div>

View file

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta charset="UTF-8">
<title>CSS Pseudo-Elements Test: active selection and image</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<link rel="help" href="https://www.w3.org/TR/css-pseudo-4/#highlight-painting">
<link rel="match" href="../reference/ref-nothing-below.xht">
<meta content="" name="flags">
<meta name="assert" content="This test checks that the associated overlay for image must not cover (or leak) outside the image's content box.">
<style>
/*
Chromium 80+ highlights the
top of line box minus
content box and the bottom
of line box minus content
box.
Firefox 72+ consistently highlights
only the image content box itself.
*/
div
{
font-size: 300px;
}
img::selection
{
background-color: red;
}
span#masking
{
background-color: white;
display: inline-block;
height: 100px;
position: relative;
right: 100px;
width: 100px;
}
</style>
<script>
function startTest()
{
var targetRange = document.createRange();
/* We first create an empty range */
targetRange.selectNodeContents(document.getElementById("test"));
/* Then we set the range boundaries to the children of div#test */
window.getSelection().addRange(targetRange);
/* Finally, we now select such range of content */
document.documentElement.className = "";
}
</script>
<body onload="startTest();">
<p>Test passes if there is nothing below.
<div id="test"><img src="support/100x100-red.png" alt="Image download support must be enabled"><span id="masking"></span></div>

View file

@ -0,0 +1,57 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
<style>
div
{
background-color: yellow;
color: green;
float: left;
font-size: 48px;
margin-left: 16px;
}
div.vrl
{
writing-mode: vertical-rl;
}
div.vlr
{
writing-mode: vertical-lr;
}
div.mixed
{
text-orientation: mixed;
}
div.sideways
{
text-orientation: sideways;
}
div.upright
{
text-orientation: upright;
}
</style>
<p>Test passes if each glyph of the 6 "Selected Text" is green and if there is <strong>no red</strong>.
<div class="vrl mixed">Selected Text</div>
<div class="vrl sideways">Selected Text</div>
<div class="vrl upright">Selected Text</div>
<div class="vlr mixed">Selected Text</div>
<div class="vlr sideways">Selected Text</div>
<div class="vlr upright">Selected Text</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

View file

@ -8,6 +8,9 @@
<script src='/resources/testdriver-vendor.js'></script> <script src='/resources/testdriver-vendor.js'></script>
<script> <script>
"use strict"; "use strict";
setup({ allow_uncaught_exception: true });
const unsupportedMethods = [ const unsupportedMethods = [
{ supportedMethods: "this-is-not-supported" }, { supportedMethods: "this-is-not-supported" },
{ supportedMethods: "https://not.supported" }, { supportedMethods: "https://not.supported" },

View file

@ -8,6 +8,9 @@
<script src="/resources/testdriver-vendor.js"></script> <script src="/resources/testdriver-vendor.js"></script>
<script> <script>
"use strict"; "use strict";
setup({ allow_uncaught_exception: true });
const defaultMethods = Object.freeze([ const defaultMethods = Object.freeze([
{ supportedMethods: "basic-card" }, { supportedMethods: "basic-card" },
{ {

View file

@ -355,6 +355,32 @@
set_user_verified: function(authenticator_id, uv) { set_user_verified: function(authenticator_id, uv) {
return window.test_driver_internal.set_user_verified(authenticator_id, uv); return window.test_driver_internal.set_user_verified(authenticator_id, uv);
}, },
/**
* Sets the storage access rule for an origin when embedded
* in a third-party context.
*
* {@link https://privacycg.github.io/storage-access/#set-storage-access-command}
*
* @param {String} origin - A third-party origin to block or allow.
* May be "*" to indicate all origins.
* @param {String} embedding_origin - an embedding (first-party) origin
* on which {origin}'s access should
* be blocked or allowed.
* May be "*" to indicate all origins.
* @param {String} state - The storage access setting.
* Must be either "allowed" or "blocked".
*
* @returns {Promise} Fulfilled after the storage access rule has been
* set, or rejected if setting the rule fails.
*/
set_storage_access: function(origin, embedding_origin, state) {
if (state !== "allowed" && state !== "blocked") {
throw new Error("storage access status must be 'allowed' or 'blocked'");
}
const blocked = state === "blocked";
return window.test_driver_internal.set_storage_access(origin, embedding_origin, blocked);
},
}; };
window.test_driver_internal = { window.test_driver_internal = {
@ -569,5 +595,13 @@
set_user_verified: function(authenticator_id, uv) { set_user_verified: function(authenticator_id, uv) {
return Promise.reject(new Error("unimplemented")); return Promise.reject(new Error("unimplemented"));
}, },
/**
* Sets the storage access policy for a third-party origin when loaded
* in the current first party context
*/
set_storage_access: function(origin, embedding_origin, blocked) {
return Promise.reject(new Error("unimplemented"));
},
}; };
})(); })();

View file

@ -0,0 +1,27 @@
def main(request, response):
name = request.GET.first(b"name")
value = request.GET.first(b"value")
testcase = request.GET.first(b"testcase")
response_headers = [(b"Set-Cookie", name + b"=" + value)]
body = b"""
<!DOCTYPE html>
<meta charset="utf-8">
<title>Set Storage Access Subframe</title>
<script src="/resources/testharness.js"></script>
<script>
let querystring = window.location.search.substring(1).split("&");
const allowed = querystring.some(param => param.toLowerCase() === "allowed=true");
test(() => {
if (allowed) {
assert_equals(document.cookie, "%s=%s");
} else {
assert_equals(document.cookie, "");
}
}, "[%s] Cookie access is allowed: " + allowed);
</script>
""" % (name, value, testcase)
return (200, response_headers, body)

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<head>
<title>TestDriver - Set Storage Access Command Tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="helpers.js"></script>
</head>
<body>
<script>
"use strict";
promise_test(async t => {
// Allow a third-party site embedded in this first-party site.
await window.test_driver.set_storage_access("http://{{domains[www]}}:{{ports[http][0]}}/", "http://{{domains[]}}:{{ports[http][0]}}/", "allowed");
// Block a third-party site embedded in this first-party site.
await window.test_driver.set_storage_access("http://{{domains[www1]}}:{{ports[http][0]}}/", "http://{{domains[]}}:{{ports[http][0]}}/", "blocked");
// Block a third-party site on all first-party sites.
await window.test_driver.set_storage_access("http://{{domains[www2]}}:{{ports[http][0]}}/", "*", "blocked");
}, "Set up storage access rules");
RunTestsInIFrame("http://{{domains[]}}:{{ports[http][0]}}/storage-access-api/resources/set-cookie.py?name=hello0&value=world0&allowed=true&testcase=same-site");
RunTestsInIFrame("http://{{domains[www]}}:{{ports[http][0]}}/storage-access-api/resources/set-cookie.py?name=hello&value=world&allowed=true&testcase=third-party-allowed-on-first-party-site");
RunTestsInIFrame("http://{{domains[www1]}}:{{ports[http][0]}}/storage-access-api/resources/set-cookie.py?name=hello1&value=world1&allowed=false&testcase=third-party-blocked-on-first-party-site");
RunTestsInIFrame("http://{{domains[www2]}}:{{ports[http][0]}}/storage-access-api/resources/set-cookie.py?name=hello2&value=world2&allowed=false&testcase=third-party-blocked-all");
</script>
</body>

View file

@ -5,7 +5,7 @@
function interceptThen() { function interceptThen() {
const intercepted = []; const intercepted = [];
const callCount = 0; let callCount = 0;
Object.prototype.then = function(resolver) { Object.prototype.then = function(resolver) {
if (!this.done) { if (!this.done) {
intercepted.push(this.value); intercepted.push(this.value);
@ -21,7 +21,7 @@ function interceptThen() {
return intercepted; return intercepted;
} }
promise_test(async () => { promise_test(async t => {
const rs = new ReadableStream({ const rs = new ReadableStream({
start(controller) { start(controller) {
controller.enqueue('a'); controller.enqueue('a');
@ -31,6 +31,9 @@ promise_test(async () => {
const ws = recordingWritableStream(); const ws = recordingWritableStream();
const intercepted = interceptThen(); const intercepted = interceptThen();
t.add_cleanup(() => {
delete Object.prototype.then;
});
await rs.pipeTo(ws); await rs.pipeTo(ws);
delete Object.prototype.then; delete Object.prototype.then;
@ -40,7 +43,7 @@ promise_test(async () => {
assert_array_equals(ws.events, ['write', 'a', 'close'], 'written chunk should be "a"'); assert_array_equals(ws.events, ['write', 'a', 'close'], 'written chunk should be "a"');
}, 'piping should not be observable'); }, 'piping should not be observable');
promise_test(async () => { promise_test(async t => {
const rs = new ReadableStream({ const rs = new ReadableStream({
start(controller) { start(controller) {
controller.enqueue('a'); controller.enqueue('a');
@ -52,6 +55,9 @@ promise_test(async () => {
const [ branch1, branch2 ] = rs.tee(); const [ branch1, branch2 ] = rs.tee();
const intercepted = interceptThen(); const intercepted = interceptThen();
t.add_cleanup(() => {
delete Object.prototype.then;
});
await branch1.pipeTo(ws); await branch1.pipeTo(ws);
delete Object.prototype.then; delete Object.prototype.then;

View file

@ -1,19 +1,25 @@
// META: global=window,worker,jsshell // META: global=window,worker,jsshell
'use strict'; 'use strict';
// Tests which patch the global environment are kept separate to avoid interfering with other tests. // Tests which patch the global environment are kept separate to avoid
// interfering with other tests.
// eslint-disable-next-line no-extend-native, accessor-pairs test(t => {
Object.defineProperty(Object.prototype, 'highWaterMark', { // eslint-disable-next-line no-extend-native, accessor-pairs
set() { throw new Error('highWaterMark setter called'); } Object.defineProperty(Object.prototype, 'highWaterMark', {
}); set() { throw new Error('highWaterMark setter called'); }
});
// eslint-disable-next-line no-extend-native, accessor-pairs // eslint-disable-next-line no-extend-native, accessor-pairs
Object.defineProperty(Object.prototype, 'size', { Object.defineProperty(Object.prototype, 'size', {
set() { throw new Error('size setter called'); } set() { throw new Error('size setter called'); }
}); });
t.add_cleanup(() => {
delete Object.prototype.highWaterMark;
delete Object.prototype.size;
});
test(() => {
assert_not_equals(new TransformStream(), null, 'constructor should work'); assert_not_equals(new TransformStream(), null, 'constructor should work');
}, 'TransformStream constructor should not call setters for highWaterMark or size'); }, 'TransformStream constructor should not call setters for highWaterMark or size');

View file

@ -199,7 +199,6 @@ def build_full_command(event, task):
~/start.sh \ ~/start.sh \
%(repo_url)s \ %(repo_url)s \
%(fetch_ref)s; %(fetch_ref)s;
sudo add-apt-repository ppa:deadsnakes/ppa
%(install_str)s %(install_str)s
cd web-platform-tests; cd web-platform-tests;
./tools/ci/run_tc.py %(options_str)s -- %(task_cmd)s; ./tools/ci/run_tc.py %(options_str)s -- %(task_cmd)s;

View file

@ -4,7 +4,7 @@ components:
workerType: ci workerType: ci
schedulerId: taskcluster-github schedulerId: taskcluster-github
deadline: "24 hours" deadline: "24 hours"
image: webplatformtests/wpt:0.42 image: webplatformtests/wpt:0.46
maxRunTime: 7200 maxRunTime: 7200
artifacts: artifacts:
public/results: public/results:
@ -392,6 +392,9 @@ tasks:
- trigger-pr - trigger-pr
- tox-python3 - tox-python3
command: ./tools/ci/ci_tools_unittest.sh command: ./tools/ci/ci_tools_unittest.sh
install:
- python3.6
- python3.6-dev
env: env:
HYPOTHESIS_PROFILE: ci HYPOTHESIS_PROFILE: ci
schedule-if: schedule-if:
@ -444,6 +447,8 @@ tasks:
command: ./tools/ci/ci_tools_integration_test.sh command: ./tools/ci/ci_tools_integration_test.sh
install: install:
- libnss3-tools - libnss3-tools
- python3.6
- python3.6-dev
options: options:
oom-killer: true oom-killer: true
browser: browser:

View file

@ -1,4 +1,4 @@
FROM ubuntu:18.04 FROM ubuntu:20.04
# No interactive frontend during docker build # No interactive frontend during docker build
ENV DEBIAN_FRONTEND=noninteractive \ ENV DEBIAN_FRONTEND=noninteractive \
@ -10,12 +10,14 @@ RUN apt-get -qqy update \
bridge-utils \ bridge-utils \
bzip2 \ bzip2 \
ca-certificates \ ca-certificates \
curl \
dbus-x11 \ dbus-x11 \
earlyoom \ earlyoom \
fluxbox \ fluxbox \
gdebi \ gdebi \
git \ git \
gstreamer1.0-plugins-bad \ gstreamer1.0-plugins-bad \
gstreamer1.0-gl \
libosmesa6-dev \ libosmesa6-dev \
libvirt-daemon-system \ libvirt-daemon-system \
libvirt-clients \ libvirt-clients \
@ -24,10 +26,12 @@ RUN apt-get -qqy update \
locales \ locales \
openjdk-8-jre-headless \ openjdk-8-jre-headless \
pulseaudio \ pulseaudio \
python \ python2 \
python-pip \ python2-dev \
python3 \ python3 \
python3-dev \
python3-pip \ python3-pip \
software-properties-common \
qemu-kvm \ qemu-kvm \
tzdata \ tzdata \
sudo \ sudo \
@ -35,6 +39,16 @@ RUN apt-get -qqy update \
wget \ wget \
xvfb xvfb
# python3.6 is not available by default in new versions of Ubuntu.
RUN apt-add-repository -y ppa:deadsnakes/ppa
# Ensure that scripts referencing `/usr/bin/env python` work.
RUN apt install python-is-python2
# The python-pip package no longer exists in new versions of Ubuntu.
RUN curl https://bootstrap.pypa.io/get-pip.py --output get-pip.py
RUN python2 get-pip.py
# Installing just the deps of firefox and chrome is moderately tricky, so # Installing just the deps of firefox and chrome is moderately tricky, so
# just install the default versions of them, and some extra deps we happen # just install the default versions of them, and some extra deps we happen
# to know that chrome requires # to know that chrome requires

View file

@ -7,7 +7,8 @@ skip_missing_interpreters = False
deps = deps =
pytest pytest
pytest-cov pytest-cov
mock # mock no longer supports Python 2 since v4
mock==3.*
hypothesis hypothesis
requests requests
taskcluster taskcluster

View file

@ -3,7 +3,6 @@ import platform
import re import re
import shutil import shutil
import stat import stat
import errno
import subprocess import subprocess
import tempfile import tempfile
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
@ -13,7 +12,7 @@ from distutils.spawn import find_executable
from six.moves.urllib.parse import urlsplit from six.moves.urllib.parse import urlsplit
import requests import requests
from .utils import call, get, untar, unzip from .utils import call, get, rmtree, untar, unzip
uname = platform.uname() uname = platform.uname()
@ -31,15 +30,6 @@ def _get_fileversion(binary, logger=None):
return None return None
def handle_remove_readonly(func, path, exc):
excvalue = exc[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777
func(path)
else:
raise
def get_ext(filename): def get_ext(filename):
"""Get the extension from a filename with special handling for .tar.foo""" """Get the extension from a filename with special handling for .tar.foo"""
name, ext = os.path.splitext(filename) name, ext = os.path.splitext(filename)
@ -63,6 +53,18 @@ class Browser(object):
def __init__(self, logger): def __init__(self, logger):
self.logger = logger self.logger = logger
def _get_dest(self, dest, channel):
if dest is None:
# os.getcwd() doesn't include the venv path
dest = os.path.join(os.getcwd(), "_venv")
dest = os.path.join(dest, "browsers", channel)
if not os.path.exists(dest):
os.makedirs(dest)
return dest
@abstractmethod @abstractmethod
def download(self, dest=None, channel=None, rename=None): def download(self, dest=None, channel=None, rename=None):
"""Download a package or installer for the browser """Download a package or installer for the browser
@ -156,18 +158,6 @@ class Firefox(Browser):
return "%s%s" % (self.platform, bits) return "%s%s" % (self.platform, bits)
def _get_dest(self, dest, channel):
if dest is None:
# os.getcwd() doesn't include the venv path
dest = os.path.join(os.getcwd(), "_venv")
dest = os.path.join(dest, "browsers", channel)
if not os.path.exists(dest):
os.makedirs(dest)
return dest
def download(self, dest=None, channel="nightly", rename=None): def download(self, dest=None, channel="nightly", rename=None):
product = { product = {
"nightly": "firefox-nightly-latest-ssl", "nightly": "firefox-nightly-latest-ssl",
@ -374,7 +364,7 @@ class Firefox(Browser):
# If we don't have a recent download, grab and extract the latest one # If we don't have a recent download, grab and extract the latest one
if not have_cache: if not have_cache:
if os.path.exists(dest): if os.path.exists(dest):
shutil.rmtree(dest) rmtree(dest)
os.makedirs(dest) os.makedirs(dest)
url = self.get_profile_bundle_url(version, channel) url = self.get_profile_bundle_url(version, channel)
@ -389,7 +379,7 @@ class Firefox(Browser):
path = os.path.join(profiles, name) path = os.path.join(profiles, name)
shutil.move(path, dest) shutil.move(path, dest)
finally: finally:
shutil.rmtree(extract_dir) rmtree(extract_dir)
else: else:
self.logger.info("Using cached test prefs from %s" % dest) self.logger.info("Using cached test prefs from %s" % dest)
@ -534,22 +524,48 @@ class Chrome(Browser):
product = "chrome" product = "chrome"
requirements = "requirements_chrome.txt" requirements = "requirements_chrome.txt"
platforms = {
"Linux": "Linux",
"Windows": "Win",
"Darwin": "Mac",
}
def __init__(self, logger):
super(Chrome, self).__init__(logger)
self._last_change = None
def download(self, dest=None, channel=None, rename=None): def download(self, dest=None, channel=None, rename=None):
raise NotImplementedError if channel != "nightly":
raise NotImplementedError("We can only download Chrome Nightly (Chromium ToT) for you.")
if dest is None:
dest = self._get_dest(None, channel)
filename = self._chromium_package_name() + ".zip"
url = self._latest_chromium_snapshot_url() + filename
self.logger.info("Downloading Chrome from %s" % url)
resp = get(url)
installer_path = os.path.join(dest, filename)
with open(installer_path, "wb") as f:
f.write(resp.content)
return installer_path
def install(self, dest=None, channel=None): def install(self, dest=None, channel=None):
raise NotImplementedError if channel != "nightly":
raise NotImplementedError("We can only install Chrome Nightly (Chromium ToT) for you.")
dest = self._get_dest(dest, channel)
def platform_string(self): installer_path = self.download(dest, channel)
platform = { with open(installer_path, "rb") as f:
"Linux": "linux", unzip(f, dest)
"Windows": "win", os.remove(installer_path)
"Darwin": "mac" return self.find_nightly_binary(dest, channel)
}.get(uname[0])
def _chromedriver_platform_string(self):
platform = self.platforms.get(uname[0])
if platform is None: if platform is None:
raise ValueError("Unable to construct a valid Chrome package name for current platform") raise ValueError("Unable to construct a valid Chrome package name for current platform")
platform = platform.lower()
if platform == "linux": if platform == "linux":
bits = "64" if uname[4] == "x86_64" else "32" bits = "64" if uname[4] == "x86_64" else "32"
@ -560,12 +576,8 @@ class Chrome(Browser):
return "%s%s" % (platform, bits) return "%s%s" % (platform, bits)
def chromium_platform_string(self): def _chromium_platform_string(self):
platform = { platform = self.platforms.get(uname[0])
"Linux": "Linux",
"Windows": "Win",
"Darwin": "Mac"
}.get(uname[0])
if platform is None: if platform is None:
raise ValueError("Unable to construct a valid Chromium package name for current platform") raise ValueError("Unable to construct a valid Chromium package name for current platform")
@ -575,7 +587,26 @@ class Chrome(Browser):
return platform return platform
def _chromium_package_name(self):
return "chrome-%s" % self.platforms.get(uname[0]).lower()
def _latest_chromium_snapshot_url(self):
# Make sure we use the same revision in an invocation.
architecture = self._chromium_platform_string()
if self._last_change is None:
revision_url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/LAST_CHANGE" % architecture
self._last_change = get(revision_url).text.strip()
return "https://storage.googleapis.com/chromium-browser-snapshots/%s/%s/" % (architecture, self._last_change)
def find_nightly_binary(self, dest, channel):
binary = "Chromium" if uname[0] == "Darwin" else "chrome"
# find_executable will add .exe on Windows automatically.
return find_executable(binary, os.path.join(dest, self._chromium_package_name()))
def find_binary(self, venv_path=None, channel=None): def find_binary(self, venv_path=None, channel=None):
if channel == "nightly":
return self.find_nightly_binary(self._get_dest(venv_path, channel))
if uname[0] == "Linux": if uname[0] == "Linux":
name = "google-chrome" name = "google-chrome"
if channel == "stable": if channel == "stable":
@ -613,25 +644,23 @@ class Chrome(Browser):
except requests.RequestException: except requests.RequestException:
return None return None
return "https://chromedriver.storage.googleapis.com/%s/chromedriver_%s.zip" % ( return "https://chromedriver.storage.googleapis.com/%s/chromedriver_%s.zip" % (
latest, self.platform_string()) latest, self._chromedriver_platform_string())
def _chromium_chromedriver_url(self, chrome_version): def _chromium_chromedriver_url(self, chrome_version):
try: if chrome_version:
# Try to find the Chromium build with the same revision. try:
omaha = get("https://omahaproxy.appspot.com/deps.json?version=" + chrome_version).json() # Try to find the Chromium build with the same revision.
revision = omaha['chromium_base_position'] omaha = get("https://omahaproxy.appspot.com/deps.json?version=" + chrome_version).json()
url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/%s/chromedriver_%s.zip" % ( revision = omaha['chromium_base_position']
self.chromium_platform_string(), revision, self.platform_string()) url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/%s/chromedriver_%s.zip" % (
# Check the status without downloading the content (this is a streaming request). self._chromium_platform_string(), revision, self._chromedriver_platform_string())
get(url) # Check the status without downloading the content (this is a streaming request).
except requests.RequestException: get(url)
# Fall back to the tip-of-tree Chromium build. return url
revision_url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/LAST_CHANGE" % ( except requests.RequestException:
self.chromium_platform_string()) pass
revision = get(revision_url).text.strip() # Fall back to the tip-of-tree Chromium build.
url = "https://storage.googleapis.com/chromium-browser-snapshots/%s/%s/chromedriver_%s.zip" % ( return "%schromedriver_%s.zip" % (self._latest_chromium_snapshot_url(), self._chromedriver_platform_string())
self.chromium_platform_string(), revision, self.platform_string())
return url
def _latest_chromedriver_url(self, chrome_version): def _latest_chromedriver_url(self, chrome_version):
# Remove channel suffixes (e.g. " dev"). # Remove channel suffixes (e.g. " dev").
@ -640,20 +669,25 @@ class Chrome(Browser):
self._chromium_chromedriver_url(chrome_version)) self._chromium_chromedriver_url(chrome_version))
def install_webdriver_by_version(self, version, dest=None): def install_webdriver_by_version(self, version, dest=None):
assert version, "Cannot install ChromeDriver without Chrome version"
if dest is None: if dest is None:
dest = os.pwd dest = os.pwd
url = self._latest_chromedriver_url(version) url = self._latest_chromedriver_url(version) if version \
else self._chromium_chromedriver_url(None)
self.logger.info("Downloading ChromeDriver from %s" % url) self.logger.info("Downloading ChromeDriver from %s" % url)
unzip(get(url).raw, dest) unzip(get(url).raw, dest)
chromedriver_dir = os.path.join( chromedriver_dir = os.path.join(
dest, 'chromedriver_%s' % self.platform_string()) dest, 'chromedriver_%s' % self._chromedriver_platform_string())
if os.path.isfile(os.path.join(chromedriver_dir, "chromedriver")): unzipped_path = find_executable("chromedriver", chromedriver_dir)
shutil.move(os.path.join(chromedriver_dir, "chromedriver"), dest) assert unzipped_path is not None
shutil.rmtree(chromedriver_dir) shutil.move(unzipped_path, dest)
rmtree(chromedriver_dir)
return find_executable("chromedriver", dest) return find_executable("chromedriver", dest)
def install_webdriver(self, dest=None, channel=None, browser_binary=None): def install_webdriver(self, dest=None, channel=None, browser_binary=None):
if channel == "nightly":
# The "nightly" channel is not an official channel, so we simply download ToT.
return self.install_webdriver_by_version(None, dest)
if browser_binary is None: if browser_binary is None:
browser_binary = self.find_binary(channel) browser_binary = self.find_binary(channel)
return self.install_webdriver_by_version( return self.install_webdriver_by_version(
@ -878,7 +912,7 @@ class Opera(Browser):
operadriver_dir = os.path.join(dest, "operadriver_%s" % self.platform_string()) operadriver_dir = os.path.join(dest, "operadriver_%s" % self.platform_string())
shutil.move(os.path.join(operadriver_dir, "operadriver"), dest) shutil.move(os.path.join(operadriver_dir, "operadriver"), dest)
shutil.rmtree(operadriver_dir) rmtree(operadriver_dir)
path = find_executable("operadriver") path = find_executable("operadriver")
st = os.stat(path) st = os.stat(path)
@ -975,7 +1009,7 @@ class EdgeChromium(Browser):
driver_notes_path = os.path.join(dest, "Driver_notes") driver_notes_path = os.path.join(dest, "Driver_notes")
if os.path.isdir(driver_notes_path): if os.path.isdir(driver_notes_path):
print("Delete %s folder" % driver_notes_path) print("Delete %s folder" % driver_notes_path)
shutil.rmtree(driver_notes_path, ignore_errors=False, onerror=handle_remove_readonly) rmtree(driver_notes_path)
self.logger.info("Downloading MSEdgeDriver from %s" % url) self.logger.info("Downloading MSEdgeDriver from %s" % url)
unzip(get(url).raw, dest) unzip(get(url).raw, dest)

View file

@ -3,7 +3,7 @@ from . import browser
latest_channels = { latest_channels = {
'firefox': 'nightly', 'firefox': 'nightly',
'chrome': 'dev', 'chrome': 'nightly',
'chrome_android': 'dev', 'chrome_android': 'dev',
'edgechromium': 'dev', 'edgechromium': 'dev',
'safari': 'preview', 'safari': 'preview',
@ -14,11 +14,11 @@ channel_by_name = {
'stable': 'stable', 'stable': 'stable',
'release': 'stable', 'release': 'stable',
'beta': 'beta', 'beta': 'beta',
'dev': 'dev',
'canary': 'canary',
'nightly': latest_channels, 'nightly': latest_channels,
'dev': latest_channels,
'preview': latest_channels, 'preview': latest_channels,
'experimental': latest_channels, 'experimental': latest_channels,
'canary': 'canary',
} }
channel_args = argparse.ArgumentParser(add_help=False) channel_args = argparse.ArgumentParser(add_help=False)

View file

@ -343,8 +343,8 @@ class Chrome(BrowserSetup):
kwargs["webdriver_binary"] = webdriver_binary kwargs["webdriver_binary"] = webdriver_binary
else: else:
raise WptrunError("Unable to locate or install chromedriver binary") raise WptrunError("Unable to locate or install chromedriver binary")
if browser_channel in ("dev", "canary"): if browser_channel in ("dev", "canary", "nightly"):
logger.info("Automatically turning on experimental features for Chrome Dev/Canary") logger.info("Automatically turning on experimental features for Chrome Dev/Canary or Chromium trunk")
kwargs["binary_args"].append("--enable-experimental-web-platform-features") kwargs["binary_args"].append("--enable-experimental-web-platform-features")
# HACK(Hexcles): work around https://github.com/web-platform-tests/wpt/issues/16448 # HACK(Hexcles): work around https://github.com/web-platform-tests/wpt/issues/16448
kwargs["webdriver_args"].append("--disable-build-check") kwargs["webdriver_args"].append("--disable-build-check")

View file

@ -16,7 +16,7 @@ except ImportError:
import pytest import pytest
from tools.wpt import wpt from tools.wpt import utils, wpt
here = os.path.abspath(os.path.dirname(__file__)) here = os.path.abspath(os.path.dirname(__file__))
@ -61,7 +61,7 @@ def manifest_dir():
os.path.join(path, "MANIFEST.json")) os.path.join(path, "MANIFEST.json"))
yield path yield path
finally: finally:
shutil.rmtree(path) utils.rmtree(path)
@pytest.fixture @pytest.fixture
@ -86,7 +86,7 @@ def temp_test():
yield make_test yield make_test
shutil.rmtree("../../.tools-tests") utils.rmtree("../../.tools-tests")
def test_missing(): def test_missing():
@ -185,6 +185,7 @@ def test_run_zero_tests():
"chrome", "/non-existent-dir/non-existent-file.html"]) "chrome", "/non-existent-dir/non-existent-file.html"])
assert excinfo.value.code != 0 assert excinfo.value.code != 0
@pytest.mark.slow @pytest.mark.slow
@pytest.mark.remote_network @pytest.mark.remote_network
def test_run_failing_test(): def test_run_failing_test():
@ -238,6 +239,25 @@ def test_run_verify_unstable(temp_test):
assert excinfo.value.code == 0 assert excinfo.value.code == 0
@pytest.mark.slow
@pytest.mark.remote_network
def test_install_chromium():
if sys.platform == "win32":
chromium_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "browsers", "nightly", "chrome-win")
elif sys.platform == "darwin":
chromium_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "browsers", "nightly", "chrome-mac")
else:
chromium_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "browsers", "nightly", "chrome-linux")
if os.path.exists(chromium_path):
utils.rmtree(chromium_path)
with pytest.raises(SystemExit) as excinfo:
wpt.main(argv=["install", "chrome", "browser", "--channel=nightly"])
assert excinfo.value.code == 0
assert os.path.exists(chromium_path)
utils.rmtree(chromium_path)
@pytest.mark.slow @pytest.mark.slow
@pytest.mark.remote_network @pytest.mark.remote_network
def test_install_chromedriver(): def test_install_chromedriver():
@ -251,7 +271,13 @@ def test_install_chromedriver():
wpt.main(argv=["install", "chrome", "webdriver"]) wpt.main(argv=["install", "chrome", "webdriver"])
assert excinfo.value.code == 0 assert excinfo.value.code == 0
assert os.path.exists(chromedriver_path) assert os.path.exists(chromedriver_path)
os.unlink(chromedriver_path) # FIXME: On Windows, this may sometimes fail (access denied), possibly
# because the file handler is not released immediately.
try:
os.unlink(chromedriver_path)
except OSError:
if sys.platform != "win32":
raise
@pytest.mark.slow @pytest.mark.slow
@ -264,12 +290,12 @@ def test_install_firefox():
else: else:
fx_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "browsers", "nightly", "firefox") fx_path = os.path.join(wpt.localpaths.repo_root, wpt.venv_dir(), "browsers", "nightly", "firefox")
if os.path.exists(fx_path): if os.path.exists(fx_path):
shutil.rmtree(fx_path) utils.rmtree(fx_path)
with pytest.raises(SystemExit) as excinfo: with pytest.raises(SystemExit) as excinfo:
wpt.main(argv=["install", "firefox", "browser", "--channel=nightly"]) wpt.main(argv=["install", "firefox", "browser", "--channel=nightly"])
assert excinfo.value.code == 0 assert excinfo.value.code == 0
assert os.path.exists(fx_path) assert os.path.exists(fx_path)
shutil.rmtree(fx_path) utils.rmtree(fx_path)
def test_files_changed(capsys): def test_files_changed(capsys):

View file

@ -8,7 +8,8 @@ deps =
pytest pytest
pytest-cov pytest-cov
hypothesis hypothesis
mock # mock no longer supports Python 2 since v4
mock==3.*
-r{toxinidir}/../wptrunner/requirements.txt -r{toxinidir}/../wptrunner/requirements.txt
-r{toxinidir}/../wptrunner/requirements_chrome.txt -r{toxinidir}/../wptrunner/requirements_chrome.txt
-r{toxinidir}/../wptrunner/requirements_firefox.txt -r{toxinidir}/../wptrunner/requirements_firefox.txt

View file

@ -1,5 +1,8 @@
import errno
import logging import logging
import os import os
import shutil
import stat
import subprocess import subprocess
import tarfile import tarfile
import zipfile import zipfile
@ -95,3 +98,19 @@ def get(url):
resp = requests.get(url, stream=True) resp = requests.get(url, stream=True)
resp.raise_for_status() resp.raise_for_status()
return resp return resp
def rmtree(path):
# This works around two issues:
# 1. Cannot delete read-only files owned by us (e.g. files extracted from tarballs)
# 2. On Windows, we sometimes just need to retry in case the file handler
# hasn't been fully released (a common issue).
def handle_remove_readonly(func, path, exc):
excvalue = exc[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777
func(path)
else:
raise
return shutil.rmtree(path, onerror=handle_remove_readonly)

View file

@ -10,7 +10,8 @@ deps =
pytest>=2.9 pytest>=2.9
pytest-cov pytest-cov
pytest-xdist pytest-xdist
mock # mock no longer supports Python 2 since v4
mock==3.*
-r{toxinidir}/requirements.txt -r{toxinidir}/requirements.txt
chrome: -r{toxinidir}/requirements_chrome.txt chrome: -r{toxinidir}/requirements_chrome.txt
edge: -r{toxinidir}/requirements_edge.txt edge: -r{toxinidir}/requirements_edge.txt