Auto merge of #27706 - servo-wpt-sync:wpt_update_16-10-2020, r=servo-wpt-sync

Sync WPT with upstream (16-10-2020)

Automated downstream sync of changes from upstream as of 16-10-2020.
[no-wpt-sync]
r? @servo-wpt-sync
This commit is contained in:
bors-servo 2020-10-16 06:38:54 -04:00 committed by GitHub
commit fd719d397c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
109 changed files with 4141 additions and 598 deletions

View file

@ -0,0 +1,4 @@
[interface-prototype-constructor-set-receiver.html]
[Window, Location, Navigator, HTMLDocument, and HTMLHeadElement]
expected: FAIL

View file

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

View file

@ -1,4 +0,0 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -1,2 +0,0 @@
[matchMedia-display-none-iframe.html]
expected: ERROR

View file

@ -312,9 +312,6 @@
[Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK] [Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK]
expected: NOTRUN expected: NOTRUN
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain] [<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL expected: FAIL
@ -324,18 +321,12 @@
[<iframe>: separate response Content-Type: text/html */*] [<iframe>: separate response Content-Type: text/html */*]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;x=" text/plain] [<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL

View file

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

View file

@ -11,3 +11,6 @@
[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

View file

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

View file

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

View file

@ -4,14 +4,14 @@
expected: FAIL expected: FAIL
[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: FAIL
[Area element should support autofocus] [Area element should support autofocus]
expected: TIMEOUT expected: NOTRUN
[Host element with delegatesFocus should support autofocus] [Host element with delegatesFocus should support autofocus]
expected: FAIL expected: TIMEOUT

View file

@ -171,6 +171,3 @@
[XHTML img usemap="#hash-id"] [XHTML img usemap="#hash-id"]
expected: FAIL expected: FAIL
[HTML (standards) IMG usemap="no-hash-name"]
expected: FAIL

View file

@ -0,0 +1,4 @@
[iframe-loading-lazy-in-script-disabled-iframe.html]
[Iframes with loading='lazy' in script disabled iframe are not handled\n as 'lazy']
expected: FAIL

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-3.html] [iframe_sandbox_popups_escaping-3.html]
expected: TIMEOUT expected: CRASH
[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,5 @@
[iframe_sandbox_popups_nonescaping-1.html] [iframe_sandbox_popups_nonescaping-1.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,5 @@
[iframe_sandbox_popups_nonescaping-2.html] [iframe_sandbox_popups_nonescaping-2.html]
expected: CRASH expected: TIMEOUT
[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: NOTRUN

View file

@ -1,5 +1,4 @@
[iframe_sandbox_popups_nonescaping-3.html] [iframe_sandbox_popups_nonescaping-3.html]
expected: TIMEOUT
[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: FAIL

View file

@ -1,4 +0,0 @@
[form-double-submit.html]
[default submit action should supersede onclick submit()]
expected: FAIL

View file

@ -0,0 +1,4 @@
[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: CRASH expected: TIMEOUT
[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

@ -140,3 +140,12 @@
[X SNR (-301.35690681171843 dB) is not greater than or equal to 85.58. Got -301.35690681171843.] [X SNR (-301.35690681171843 dB) is not greater than or equal to 85.58. Got -301.35690681171843.]
expected: FAIL expected: FAIL
[X SNR (43.80469175702206 dB) is not greater than or equal to 65.737. Got 43.80469175702206.]
expected: FAIL
[X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[28696\]\t-2.1886497270315886e-3\t9.3139332532882690e-1\t9.3358197505585849e-1\t1.0023498662353618e+0\t3.8985999999999999e-3\n\t[28697\]\t7.0477002859115601e-1\t9.0675884485244751e-1\t2.0198881626129150e-1\t2.2275913536212616e-1\t3.8985999999999999e-3\n\tMax AbsError of 9.3358197505585849e-1 at index of 28696.\n\tMax RelError of 1.0023498662353618e+0 at index of 28696.\n]
expected: FAIL
[< [buffer-stitching-2\] 2 out of 3 assertions were failed.]
expected: FAIL

View file

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

View file

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

View file

@ -413,6 +413,15 @@
} }
}, },
"css-sizing": { "css-sizing": {
"aspect-ratio": {
"small-aspect-ratio-crash.html": [
"07712542f179c5e83cc44f4f15130c48e030d8c0",
[
null,
{}
]
]
},
"frameset-intrinsic-crash.html": [ "frameset-intrinsic-crash.html": [
"ab9c43ee44d6c838597074152e1a7463644d29b1", "ab9c43ee44d6c838597074152e1a7463644d29b1",
[ [
@ -18280,13 +18289,6 @@
{} {}
] ]
], ],
"show-method-optional-promise-rejects-manual.https.html": [
"1a322452eb6114630b2f0d1d2a9762092ad5ebb9",
[
null,
{}
]
],
"show-method-optional-promise-resolves-manual.https.html": [ "show-method-optional-promise-resolves-manual.https.html": [
"5360a9704af459f30180f938d12828f6dbf1b570", "5360a9704af459f30180f938d12828f6dbf1b570",
[ [
@ -150544,6 +150546,19 @@
{} {}
] ]
], ],
"percentage-size-subitems-002.html": [
"17f57bf39d1910bdc02fd9fd4f1c9865c63cc109",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square-only.html",
"=="
]
],
{}
]
],
"remove-svg-grid-item-001.html": [ "remove-svg-grid-item-001.html": [
"5e196c82c64bb52ee5b445b664eb5bc0dbd60573", "5e196c82c64bb52ee5b445b664eb5bc0dbd60573",
[ [
@ -152234,6 +152249,19 @@
] ]
] ]
}, },
"relative-grandchild.html": [
"9c1b7d54e1f568e13e656a3bc57a840cdc93bcf2",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"subgrid": { "subgrid": {
"abs-pos-001.html": [ "abs-pos-001.html": [
"e524ec2d767c043516546733411d7e25e6eff05b", "e524ec2d767c043516546733411d7e25e6eff05b",
@ -157647,6 +157675,32 @@
{} {}
] ]
], ],
"clip-path-path-interpolation-with-zoom.html": [
"4d54708da198d2c35bc5980857a8248b9159d3d4",
[
null,
[
[
"/css/css-masking/clip-path/reference/clip-path-path-interpolation-with-zoom-ref.html",
"=="
]
],
{}
]
],
"clip-path-path-with-zoom.html": [
"5879917f36e7efb74db4b1aaeb8a05bee96f39cd",
[
null,
[
[
"/css/css-masking/clip-path/reference/clip-path-path-with-zoom-ref.html",
"=="
]
],
{}
]
],
"clip-path-polygon-001.html": [ "clip-path-polygon-001.html": [
"954f0ba8d91de74cb36b834f06db5a00ad59b194", "954f0ba8d91de74cb36b834f06db5a00ad59b194",
[ [
@ -158520,6 +158574,19 @@
{} {}
] ]
], ],
"clip-path-no-content-005.svg": [
"e0c03d28cb0509e31ffb12034a138e0fb9b43da1",
[
null,
[
[
"/css/css-masking/clip-path-svg-content/reference/clip-path-square-003-ref.svg",
"=="
]
],
{}
]
],
"clip-path-objectboundingbox-001.svg": [ "clip-path-objectboundingbox-001.svg": [
"d5ef03ac01166554fa573dda10496e598300c82b", "d5ef03ac01166554fa573dda10496e598300c82b",
[ [
@ -239470,6 +239537,102 @@
} }
} }
}, },
"density-size-correction": {
"density-corrected-image-svg-aspect-ratio.html": [
"fbc68de65db86477eddae60bb122a6712123a574",
[
null,
[
[
"/density-size-correction/density-corrected-image-svg-aspect-ratio-ref.html",
"=="
]
],
{
"fuzzy": [
[
null,
[
[
10,
10
],
[
100,
100
]
]
]
]
}
]
],
"density-corrected-image-svg.html": [
"91c94965edd8b6abb6bd9425d7010acbc67c33fb",
[
null,
[
[
"/density-size-correction/density-corrected-image-svg-ref.html",
"=="
]
],
{}
]
],
"density-corrected-size-bg.html": [
"5a3190ebceab0fbab6072962060e3b3c87229b94",
[
null,
[
[
"/density-size-correction/density-corrected-size-bg-ref.html",
"=="
]
],
{}
]
],
"density-corrected-size-img.html": [
"7c2e788acb9661696365552922f5db721f0fc08b",
[
null,
[
[
"/density-size-correction/density-corrected-size-img-ref.html",
"=="
]
],
{}
]
],
"density-corrected-size-pseudo-elements.html": [
"34d318f1a2a4a10904c69cf3675cfd084d1cdca8",
[
null,
[
[
"/density-size-correction/density-corrected-size-pseudo-elements-ref.html",
"=="
]
],
{}
]
],
"density-corrected-various-elements.html": [
"69d80564b669abb4f59030f022688ac91225ab47",
[
null,
[
[
"/density-size-correction/density-corrected-various-elements-ref.html",
"=="
]
],
{}
]
]
},
"document-policy": { "document-policy": {
"font-display": { "font-display": {
"override-to-optional.tentative.html": [ "override-to-optional.tentative.html": [
@ -279593,6 +279756,16 @@
[] []
] ]
}, },
"cors-rfc1918": {
"META.yml": [
"7f0d420a0e6f040497827a1cf19cb7b39d55922a",
[]
],
"README.md": [
"f641b61971e8b09de644476d2e04a1e45890b633",
[]
]
},
"credential-management": { "credential-management": {
"META.yml": [ "META.yml": [
"7b1860921312cc9d9934aa803e3f639df21423a0", "7b1860921312cc9d9934aa803e3f639df21423a0",
@ -279612,11 +279785,11 @@
[] []
], ],
"otpcredential-helper.js": [ "otpcredential-helper.js": [
"0c6ce8b1f38ca321900efae35a53977da9370acb", "e07e9f5be359e9173b6c916d91d8ce1f87260885",
[] []
], ],
"otpcredential-iframe.html": [ "otpcredential-iframe.html": [
"83f25d573c8ecc967635bb9239a3d0c0c1544d37", "4affc00ecde9951aa2911a7e818615600f324d8f",
[] []
], ],
"passwordcredential-get.html": [ "passwordcredential-get.html": [
@ -311165,6 +311338,14 @@
"567764a30124c2bc8821a508e2a7f8b6f0787c7e", "567764a30124c2bc8821a508e2a7f8b6f0787c7e",
[] []
], ],
"clip-path-path-interpolation-with-zoom-ref.html": [
"7e0d2a54266f3855dbc8e8e87167a06ea0cc323b",
[]
],
"clip-path-path-with-zoom-ref.html": [
"ef91c619c40615f633c64d59bfe302fcfbd8c5fb",
[]
],
"clip-path-rectangle-border-ref.html": [ "clip-path-rectangle-border-ref.html": [
"9a61c7690248f48ba123535524bf1bff60b4016c", "9a61c7690248f48ba123535524bf1bff60b4016c",
[] []
@ -329635,6 +329816,82 @@
} }
} }
}, },
"density-size-correction": {
"density-corrected-image-svg-aspect-ratio-ref.html": [
"fa13136876c88b8e3b32d68c2c0155862151c51b",
[]
],
"density-corrected-image-svg-ref.html": [
"6507c66982903ebbbaf2de88843de6a7f3dfed65",
[]
],
"density-corrected-size-bg-ref.html": [
"758ca8edc60adccf491f7db3aa40dbba9d75798b",
[]
],
"density-corrected-size-img-ref.html": [
"5a71863a46e9e2ce14abd717230becdea77f1c58",
[]
],
"density-corrected-size-pseudo-elements-ref.html": [
"b2c9de4114e1e69192c8436beecc7ae3d07ce061",
[]
],
"density-corrected-various-elements-ref.html": [
"a0be0ac8d80f541038d0cdd1132afa4a05220392",
[]
],
"resources": {
"exif-resolution-no-change.jpg": [
"04f9202cfcc5ffcf5934b42c0fff9e7c4b0c541e",
[]
],
"exif-resolution-none.jpg": [
"04f9202cfcc5ffcf5934b42c0fff9e7c4b0c541e",
[]
],
"exif-resolution-preapplied-lores.jpg": [
"ad91a1479897ca221d743bbe314798f3e73902fa",
[]
],
"exif-resolution-preapplied-non-uniform.jpg": [
"c1a607f0b041c4bd110650a6f59c7650f71ecc14",
[]
],
"exif-resolution-valid-hires.jpg": [
"757ce2d877d8ac6e2cfb777e3145fabf0d946085",
[]
],
"exif-resolution-valid-lores.jpg": [
"11a5d8b12e1df4fa984601b62e1b645278774d7d",
[]
],
"exif-resolution-valid-non-uniform.jpg": [
"a028bde2e8479532ffb37483b0cdce944c1b1a78",
[]
],
"exif-resolution-with-orientation.jpg": [
"5c914f03fffbf650a9e224691666f90cfb6583b6",
[]
],
"exify.js": [
"c16b25e8676afef23133c2b35c1c6dc5623af473",
[]
]
},
"third_party": {
"piexif": {
"LICENSE.txt": [
"73bd9746b25f2c7d43c2bafe57043ef306304411",
[]
],
"piexif.js": [
"01b4e8f108a34f690fd2e6cafcc0c1a7f385c309",
[]
]
}
}
},
"device-memory": { "device-memory": {
"META.yml": [ "META.yml": [
"b8dd4761adff3e18b6552d4a8f02abdcd30a3ea6", "b8dd4761adff3e18b6552d4a8f02abdcd30a3ea6",
@ -343776,6 +344033,10 @@
[] []
], ],
"resources": { "resources": {
"iframe-loading-lazy-in-viewport.html": [
"1efd2bd056dde80de03448a76b9bd28f94fd1795",
[]
],
"subframe.html": [ "subframe.html": [
"07cb999afaefe344a0f8d5ac2b792b60abcd22b4", "07cb999afaefe344a0f8d5ac2b792b60abcd22b4",
[] []
@ -353543,10 +353804,6 @@
"6805c323df5a975231648b830e33ce183c3cbbd3", "6805c323df5a975231648b830e33ce183c3cbbd3",
[] []
], ],
"mock-sms-receiver.js": [
"903456d6830481cfd8d977120105359d4fc43774",
[]
],
"mock-textdetection.js": [ "mock-textdetection.js": [
"427ce38da21a9cd00e11aab313708f2719d8b094", "427ce38da21a9cd00e11aab313708f2719d8b094",
[] []
@ -353772,7 +354029,7 @@
[] []
], ],
"no-title.html": [ "no-title.html": [
"3458af4459674c89de7529aecbc6a0b6de233757", "ae1333a0f7f890b1b5e44a8a5ef3116fd4f5885b",
[] []
], ],
"order.html": [ "order.html": [
@ -354020,7 +354277,7 @@
} }
}, },
"tox.ini": [ "tox.ini": [
"a7a02e4b93bdc009ef0b05cbc039c3977fcdd46e", "c38b9f2749c8c0f8b5820ca3c621e396d4a14c7e",
[] []
], ],
"variants.js": [ "variants.js": [
@ -354040,6 +354297,14 @@
"5e8f640c6659d176eaca4c71cc1798b7285540b7", "5e8f640c6659d176eaca4c71cc1798b7285540b7",
[] []
], ],
"test-only-api.m.js": [
"984f635abac00272304c78f2f5bb99b397b27523",
[]
],
"test-only-api.m.js.headers": [
"5e8f640c6659d176eaca4c71cc1798b7285540b7",
[]
],
"testdriver-actions.js": [ "testdriver-actions.js": [
"f3e6388e8acd1998d89750150e0779df327a5417", "f3e6388e8acd1998d89750150e0779df327a5417",
[] []
@ -354061,7 +354326,7 @@
[] []
], ],
"testharness.js": [ "testharness.js": [
"85ffcf726af1b634a9e5bc1fc35aca56deb74b4c", "4fb8cea0bcc167c99448c5b680276ebb1413cb5e",
[] []
], ],
"testharness.js.headers": [ "testharness.js.headers": [
@ -358474,7 +358739,7 @@
[] []
], ],
"epochs_update.sh": [ "epochs_update.sh": [
"f460814c962076b4ec72c072dff09925427c90a6", "1c7edf15aaf8c47638393291de1724e41bab8a2d",
[] []
], ],
"jobs.py": [ "jobs.py": [
@ -365282,7 +365547,7 @@
[] []
], ],
"chrome.py": [ "chrome.py": [
"486070ad86d451e73f0e56ce720134024ffc1121", "fd251a431c306f3bb3b12b848f548d8eff07a466",
[] []
], ],
"chrome_android.py": [ "chrome_android.py": [
@ -383963,6 +384228,13 @@
{} {}
] ]
], ],
"interface-prototype-constructor-set-receiver.html": [
"20f33f243abeef901357fb2026f0fe2182277673",
[
null,
{}
]
],
"interface-prototype-object.html": [ "interface-prototype-object.html": [
"d2d43eda9a94688ffd707a3ed8f89c28e74324c4", "d2d43eda9a94688ffd707a3ed8f89c28e74324c4",
[ [
@ -396144,7 +396416,7 @@
] ]
], ],
"otpcredential-get-basics.https.html": [ "otpcredential-get-basics.https.html": [
"edeb42a0f579209c1556d83c7fa98de08757f0dc", "c0cac166de91c242a16bd4d6fc2edfa93aa37680",
[ [
null, null,
{} {}
@ -399462,6 +399734,13 @@
null, null,
{} {}
] ]
],
"CSS-supports.html": [
"dbe9506de149be2fbb1e28d1b334dbdd5dcbbbe6",
[
null,
{}
]
] ]
}, },
"test_group_insertRule.html": [ "test_group_insertRule.html": [
@ -406693,6 +406972,13 @@
] ]
}, },
"clip-path": { "clip-path": {
"clip-path-path-with-zoom-hittest.html": [
"30ceefcbc03980564136ad29b6fd1a8f9a318d38",
[
null,
{}
]
],
"interpolation.html": [ "interpolation.html": [
"da3981feed6ed681ee4a7d88b7ecd167b9fd5c7b", "da3981feed6ed681ee4a7d88b7ecd167b9fd5c7b",
[ [
@ -419245,13 +419531,6 @@
{} {}
] ]
], ],
"CSS.html": [
"ba048c58acaac5cd2550fb21cb9b6e9ee8fb0bb1",
[
null,
{}
]
],
"CSSCounterStyleRule.html": [ "CSSCounterStyleRule.html": [
"afae84b0b25f4aebf2461179cf5a5a2b769cce4f", "afae84b0b25f4aebf2461179cf5a5a2b769cce4f",
[ [
@ -419715,7 +419994,7 @@
] ]
], ],
"escape.html": [ "escape.html": [
"721c6ea35572d42e2782d6f40f7e73539df35b3a", "895da59c49c0495514f0002fa6c340059c1d3123",
[ [
null, null,
{} {}
@ -423323,6 +423602,22 @@
] ]
] ]
}, },
"density-size-correction": {
"density-corrected-image-in-canvas.html": [
"25ac0954d3a588cdf51dd1df4108ecf5d0ea99e6",
[
null,
{}
]
],
"density-corrected-natural-size.html": [
"0b90b74f439b587f0aabb393c72a42db1a23ad61",
[
null,
{}
]
]
},
"deprecation-reporting": { "deprecation-reporting": {
"idlharness.any.js": [ "idlharness.any.js": [
"720bacfa3ff3f00e2b8dcc4e061924d2dc48e876", "720bacfa3ff3f00e2b8dcc4e061924d2dc48e876",
@ -473629,6 +473924,13 @@
{} {}
] ]
], ],
"iframe-loading-lazy-in-script-disabled-iframe.html": [
"4f191cd7842675d763079911fe9f8b80bd447506",
[
null,
{}
]
],
"iframe-loading-lazy-load-event.html": [ "iframe-loading-lazy-load-event.html": [
"bf98bf7585cf608e6ebb46d025663e22bce8324c", "bf98bf7585cf608e6ebb46d025663e22bce8324c",
[ [
@ -489968,6 +490270,13 @@
null, null,
{} {}
] ]
],
"onmerchantvalidation-attribute.https.html": [
"d31ac2dd72abcf51a28ecec850400f5f0c6b9bb5",
[
null,
{}
]
] ]
}, },
"mimesniff": { "mimesniff": {
@ -496499,13 +496808,6 @@
} }
] ]
], ],
"onmerchantvalidation-attribute.https.html": [
"d31ac2dd72abcf51a28ecec850400f5f0c6b9bb5",
[
null,
{}
]
],
"onpaymentmethodchange-attribute.https.html": [ "onpaymentmethodchange-attribute.https.html": [
"f641bec4aa91d8be4f1801869eb699ca4bad03a0", "f641bec4aa91d8be4f1801869eb699ca4bad03a0",
[ [
@ -496524,16 +496826,7 @@
] ]
], ],
"payment-request-abort-method.https.html": [ "payment-request-abort-method.https.html": [
"8230e2458aaa3e0364dc45985f596759f009547d", "32b87970b4df49d2eef4945e3869f4abfcaa537a",
[
null,
{
"testdriver": true
}
]
],
"payment-request-canmakepayment-method-protection.https.html": [
"9c068dfe001e35d57783a0e99f3d6edd50cc5795",
[ [
null, null,
{ {
@ -496655,7 +496948,7 @@
] ]
], ],
"payment-request-show-method.https.html": [ "payment-request-show-method.https.html": [
"20d5bab0d14b79fb3dcf3e82e08dc495d038a33d", "e5ee5eed01b26c872d01f801bb0739f791b5be58",
[ [
null, null,
{ {
@ -496681,11 +496974,22 @@
} }
] ]
], ],
"secure-payment-confirmation.https.html": [ "show-consume-activation.https.html": [
"1cc12d49eba1369d57512a52de30eab4fa477da2", "0b92c4c15cf158457a9cfae6fab02171a49ca5f2",
[ [
null, null,
{} {
"testdriver": true
}
]
],
"show-method-optional-promise-rejects.https.html": [
"3b42965503922d88213409dc814300c05b3a672f",
[
null,
{
"testdriver": true
}
] ]
] ]
}, },
@ -511065,7 +511369,7 @@
] ]
], ],
"element-based-offset-clamp.html": [ "element-based-offset-clamp.html": [
"b140507493848688f38021573643ce7d6321e514", "6467af199f10224e16f07badf16b73593270f14c",
[ [
null, null,
{} {}
@ -511353,6 +511657,15 @@
] ]
] ]
}, },
"secure-payment-confirmation": {
"secure-payment-confirmation.tenative.https.html": [
"1cc12d49eba1369d57512a52de30eab4fa477da2",
[
null,
{}
]
]
},
"selection": { "selection": {
"Document-open.html": [ "Document-open.html": [
"9e3cb28124c0d65f61d1e71672c2429a3b64a792", "9e3cb28124c0d65f61d1e71672c2429a3b64a792",
@ -526952,7 +527265,7 @@
] ]
], ],
"urlsearchparams-constructor.any.js": [ "urlsearchparams-constructor.any.js": [
"1135d5d3dbbfa3625391e090985231c41e88f2c6", "f9878373e5e067598054df4682652a0e9ced270a",
[ [
"url/urlsearchparams-constructor.any.html", "url/urlsearchparams-constructor.any.html",
{} {}

View file

@ -0,0 +1,4 @@
[interface-prototype-constructor-set-receiver.html]
[Window, Location, Navigator, HTMLDocument, and HTMLHeadElement]
expected: FAIL

View file

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

View file

@ -1,4 +0,0 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -1,2 +0,0 @@
[matchMedia-display-none-iframe.html]
expected: ERROR

View file

@ -312,9 +312,6 @@
[fetch(): separate response Content-Type: text/plain ] [fetch(): separate response Content-Type: text/plain ]
expected: NOTRUN expected: NOTRUN
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain] [<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL expected: FAIL
@ -324,18 +321,12 @@
[<iframe>: separate response Content-Type: text/html */*] [<iframe>: separate response Content-Type: text/html */*]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;x=" text/plain] [<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL expected: FAIL
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL

View file

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

View file

@ -11,3 +11,6 @@
[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

View file

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

View file

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

View file

@ -7,11 +7,11 @@
expected: FAIL expected: FAIL
[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: TIMEOUT expected: NOTRUN
[Host element with delegatesFocus should support autofocus] [Host element with delegatesFocus should support autofocus]
expected: FAIL expected: TIMEOUT

View file

@ -172,6 +172,3 @@
[XHTML img usemap="http://example.org/#garbage-before-hash-id"] [XHTML img usemap="http://example.org/#garbage-before-hash-id"]
expected: FAIL expected: FAIL
[HTML (standards) IMG usemap="no-hash-name"]
expected: FAIL

View file

@ -0,0 +1,4 @@
[iframe-loading-lazy-in-script-disabled-iframe.html]
[Iframes with loading='lazy' in script disabled iframe are not handled\n as 'lazy']
expected: FAIL

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_escaping-3.html] [iframe_sandbox_popups_escaping-3.html]
type: testharness type: testharness
expected: TIMEOUT expected: CRASH
[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,6 @@
[iframe_sandbox_popups_nonescaping-1.html] [iframe_sandbox_popups_nonescaping-1.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,6 @@
[iframe_sandbox_popups_nonescaping-2.html] [iframe_sandbox_popups_nonescaping-2.html]
type: testharness type: testharness
expected: CRASH expected: TIMEOUT
[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: NOTRUN

View file

@ -1,6 +1,5 @@
[iframe_sandbox_popups_nonescaping-3.html] [iframe_sandbox_popups_nonescaping-3.html]
type: testharness type: testharness
expected: TIMEOUT
[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: FAIL

View file

@ -1,4 +0,0 @@
[form-double-submit.html]
[default submit action should supersede onclick submit()]
expected: FAIL

View file

@ -0,0 +1,4 @@
[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: CRASH expected: TIMEOUT
[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

@ -371,3 +371,9 @@
[X SNR (-301.35690681171843 dB) is not greater than or equal to 85.58. Got -301.35690681171843.] [X SNR (-301.35690681171843 dB) is not greater than or equal to 85.58. Got -301.35690681171843.]
expected: FAIL expected: FAIL
[X SNR (43.80469175702206 dB) is not greater than or equal to 65.737. Got 43.80469175702206.]
expected: FAIL
[X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[28696\]\t-2.1886497270315886e-3\t9.3139332532882690e-1\t9.3358197505585849e-1\t1.0023498662353618e+0\t3.8985999999999999e-3\n\t[28697\]\t7.0477002859115601e-1\t9.0675884485244751e-1\t2.0198881626129150e-1\t2.2275913536212616e-1\t3.8985999999999999e-3\n\tMax AbsError of 9.3358197505585849e-1 at index of 28696.\n\tMax RelError of 1.0023498662353618e+0 at index of 28696.\n]
expected: FAIL

View file

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

View file

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

View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Interface.prototype.constructor is defined on [[Set]] receiver</title>
<link rel="help" href="https://heycam.github.io/webidl/#interface-prototype-object">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
window.constructor = null;
assert_equals(Window.prototype.constructor, Window);
location.constructor = false;
assert_equals(Location.prototype.constructor, Location);
navigator.constructor = 1;
assert_equals(Navigator.prototype.constructor, Navigator);
document.constructor = {};
assert_equals(HTMLDocument.prototype.constructor, HTMLDocument);
document.head.constructor = [];
assert_equals(HTMLHeadElement.prototype.constructor, HTMLHeadElement);
}, "Window, Location, Navigator, HTMLDocument, and HTMLHeadElement");
test(() => {
for (let key of Object.getOwnPropertyNames(window)) {
if (!/^[A-Z]/.test(key)) continue;
let desc = Object.getOwnPropertyDescriptor(window, key);
if (!desc || desc.enumerable) continue;
let {value} = desc;
if (typeof value !== "function") continue;
let {prototype} = value;
if (!prototype) continue;
let heir = Object.create(prototype);
let newConstructor = function() {};
heir.constructor = newConstructor;
assert_not_equals(prototype.constructor, newConstructor, key);
assert_own_property(heir, "constructor", key);
assert_equals(heir.constructor, newConstructor, key);
}
}, "All window.* constructors");
</script>

View file

@ -0,0 +1,5 @@
spec: https://wicg.github.io/cors-rfc1918/
suggested_reviewers:
- letitz
- camillelamy
- mikewest

View file

@ -0,0 +1,8 @@
# CORS-RFC1918 tests
This directory contains tests for CORS-RFC1918. See also:
* [The specification](https://wicg.github.io/cors-rfc1918/)
* [The repository](https://github.com/WICG/cors-rfc1918/)
* [Open issues](https://github.com/WICG/cors-rfc1918/issues/)
* Additional tests: ../fetch/cors-rfc1918/

View file

@ -3,15 +3,12 @@
<title>Tests OTPCredential</title> <title>Tests OTPCredential</title>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/resources/test-only-api.js"></script> <script type="module">
<script src="support/otpcredential-helper.js"></script> import {Status, expectOTPRequest} from './support/otpcredential-helper.js';
<script>
'use strict';
promise_test(async t => { promise_test(async t => {
await expect(receive).andReturn(async () => { await expectOTPRequest().andReturn(
return {status: Status.kSuccess, otp: "ABC"}; () => ({status: Status.SUCCESS, otp: "ABC"}));
});
let cred = await navigator.credentials.get({otp: {transport: ["sms"]}}); let cred = await navigator.credentials.get({otp: {transport: ["sms"]}});
@ -19,17 +16,15 @@ promise_test(async t => {
}, 'Basic usage'); }, 'Basic usage');
promise_test(async t => { promise_test(async t => {
await expect(receive).andReturn(async () => { await expectOTPRequest().andReturn(
return {status: Status.kSuccess, otp: "ABC"}; () => ({status: Status.SUCCESS, otp: "ABC"}));
}); await expectOTPRequest().andReturn(
await expect(receive).andReturn(async () => { () => ({status: Status.SUCCESS, otp: "ABC2"}));
return {status: Status.kSuccess, otp: "ABC2"};
});
let sms1 = navigator.credentials.get({otp: {transport: ["sms"]}}); let sms1 = navigator.credentials.get({otp: {transport: ["sms"]}});
let sms2 = navigator.credentials.get({otp: {transport: ["sms"]}}); let sms2 = navigator.credentials.get({otp: {transport: ["sms"]}});
let cred2= await sms2; let cred2 = await sms2;
let cred1 = await sms1; let cred1 = await sms1;
assert_equals(cred1.code, "ABC"); assert_equals(cred1.code, "ABC");
@ -37,21 +32,18 @@ promise_test(async t => {
}, 'Handle multiple requests in different order.'); }, 'Handle multiple requests in different order.');
promise_test(async t => { promise_test(async t => {
await expect(receive).andReturn(async () => { await expectOTPRequest().andReturn(() => ({status: Status.CANCELLED}));
return {status: Status.kCancelled}; await expectOTPRequest().andReturn(
}); () => ({status: Status.SUCCESS, otp: "success"}));
await expect(receive).andReturn(async () => {
return {status: Status.kSuccess, otp: "success"};
});
let cancelled_sms = navigator.credentials.get({otp: {transport: ["sms"]}}); let cancelledRequest = navigator.credentials.get({otp: {transport: ["sms"]}});
let successful_sms = navigator.credentials.get({otp: {transport: ["sms"]}}); let successfulCred =
await navigator.credentials.get({otp: {transport: ["sms"]}});
let successful_cred = await successful_sms; assert_equals(successfulCred.code, "success");
assert_equals(successful_cred.code, "success");
try { try {
await cancelled_sms; await cancelledRequest;
assert_unreached('Expected AbortError to be thrown.'); assert_unreached('Expected AbortError to be thrown.');
} catch (error) { } catch (error) {
assert_equals(error.name, "AbortError"); assert_equals(error.name, "AbortError");
@ -59,9 +51,7 @@ promise_test(async t => {
}, 'Handle multiple requests with success and error.'); }, 'Handle multiple requests with success and error.');
promise_test(async t => { promise_test(async t => {
await expect(receive).andReturn(async () => { await expectOTPRequest().andReturn(() => ({status: Status.CANCELLED}));
return {status: Status.kCancelled};
});
await promise_rejects_dom(t, 'AbortError', navigator.credentials.get( await promise_rejects_dom(t, 'AbortError', navigator.credentials.get(
{otp: {transport: ["sms"]}})); {otp: {transport: ["sms"]}}));

View file

@ -1,52 +1,114 @@
'use strict';
// These tests rely on the User Agent providing an implementation of // These tests rely on the User Agent providing an implementation of
// the sms retriever. // MockWebOTPService.
// //
// In Chromium-based browsers this implementation is provided by a polyfill // In Chromium-based browsers this implementation is provided by a polyfill
// in order to reduce the amount of test-only code shipped to users. To enable // in order to reduce the amount of test-only code shipped to users. To enable
// these tests the browser must be run with these options: // these tests the browser must be run with these options:
// // --enable-blink-features=MojoJS,MojoJSTest // // --enable-blink-features=MojoJS,MojoJSTest
const Status = {}; import {isChromiumBased} from '/resources/test-only-api.m.js';
async function loadChromiumResources() { /**
const resources = [ * This enumeration is used by WebOTP WPTs to control mock backend behavior.
'/gen/mojo/public/mojom/base/time.mojom-lite.js', * See MockWebOTPService below.
'/gen/third_party/blink/public/mojom/sms/webotp_service.mojom-lite.js', */
]; export const Status = {
SUCCESS: 0,
await loadMojoResources(resources, true); UNHANDLED_REQUEST: 1,
await loadScript('/resources/chromium/mock-sms-receiver.js'); CANCELLED: 2,
ABORTED: 3,
Status.kSuccess = blink.mojom.SmsStatus.kSuccess;
Status.kTimeout = blink.mojom.SmsStatus.kTimeout;
Status.kCancelled = blink.mojom.SmsStatus.kCancelled;
}; };
async function create_sms_provider() { /**
if (typeof SmsProvider === 'undefined') { * A interface which must be implemented by browsers to support WebOTP WPTs.
if (isChromiumBased) { */
await loadChromiumResources(); export class MockWebOTPService {
} else { /**
throw new Error('Mojo testing interface is not available.'); * Accepts a function to be invoked in response to the next OTP request
} * received by the mock. The (optionally async) function, when executed, must
} * return an object with a `status` field holding one of the `Status` values
if (typeof SmsProvider === 'undefined') { * defined above, and -- if successful -- an `otp` field containing a
throw new Error('Failed to set up SmsProvider.'); * simulated OTP string.
} *
return new SmsProvider(); * Tests will call this method directly to inject specific response behavior
* into the browser-specific mock implementation.
*/
async handleNextOTPRequest(responseFunc) {}
} }
function receive() { /**
throw new Error("expected to be overriden by tests"); * Returns a Promise resolving to a browser-specific MockWebOTPService subclass
* instance if one is available.
*/
async function createBrowserSpecificMockImpl() {
if (isChromiumBased) {
return await createChromiumMockImpl();
}
throw new Error('Unsupported browser.');
} }
function expect(call) { const asyncMock = createBrowserSpecificMockImpl();
export function expectOTPRequest() {
return { return {
async andReturn(callback) { async andReturn(callback) {
const mock = await create_sms_provider(); const mock = await asyncMock;
mock.pushReturnValuesForTesting(call.name, callback); mock.handleNextOTPRequest(callback);
} }
} }
} }
/**
* Instantiates a Chromium-specific subclass of MockWebOTPService.
*/
async function createChromiumMockImpl() {
const {SmsStatus, WebOTPService, WebOTPServiceReceiver} = await import(
'/gen/third_party/blink/public/mojom/sms/webotp_service.mojom.m.js');
const MockWebOTPServiceChromium = class extends MockWebOTPService {
constructor() {
super();
this.mojoReceiver_ = new WebOTPServiceReceiver(this);
this.interceptor_ =
new MojoInterfaceInterceptor(WebOTPService.$interfaceName);
this.interceptor_.oninterfacerequest = (e) => {
this.mojoReceiver_.$.bindHandle(e.handle);
};
this.interceptor_.start();
this.requestHandlers_ = [];
Object.freeze(this);
}
handleNextOTPRequest(responseFunc) {
this.requestHandlers_.push(responseFunc);
}
async receive() {
if (this.requestHandlers_.length == 0) {
throw new Error('Mock received unexpected OTP request.');
}
const responseFunc = this.requestHandlers_.shift();
const response = await responseFunc();
switch (response.status) {
case Status.SUCCESS:
if (typeof response.otp != 'string') {
throw new Error('Mock success results require an OTP string.');
}
return {status: SmsStatus.kSuccess, otp: response.otp};
case Status.UNHANDLED_REQUEST:
return {status: SmsStatus.kUnhandledRequest};
case Status.CANCELLED:
return {status: SmsStatus.kCancelled};
case Status.ABORTED:
return {status: SmsStatus.kAborted};
default:
throw new Error(
`Mock result contains unknown status: ${response.status}`);
}
}
async abort() {}
};
return new MockWebOTPServiceChromium();
}

View file

@ -1,8 +1,6 @@
<!doctype html> <!doctype html>
<script src="/resources/test-only-api.js"></script> <script type="module">
<script src="otpcredential-helper.js"></script> import {Status, expectOTPRequest} from './otpcredential-helper.js';
<script>
'use strict';
// Loading otpcredential-iframe.html in the test will make an OTPCredentials // Loading otpcredential-iframe.html in the test will make an OTPCredentials
// call on load, and trigger a postMessage upon completion. // call on load, and trigger a postMessage upon completion.
@ -13,24 +11,16 @@
// string errorType: error.name // string errorType: error.name
// } // }
// Intercept successful calls and return mocked value.
(async function() {
await expect(receive).andReturn(() => {
return Promise.resolve({
status: Status.kSuccess,
otp: "ABC123",
});
});
}());
window.onload = async () => { window.onload = async () => {
try { try {
const credentials = await expectOTPRequest().andReturn(
await navigator.credentials.get({otp: {transport: ["sms"]}}); () => ({status: Status.SUCCESS, otp: "ABC123"}));
window.parent.postMessage({result: "Pass", code: credentials.code}, '*'); const credentials =
} catch (error) { await navigator.credentials.get({otp: {transport: ["sms"]}});
window.parent.postMessage({result: "Fail", errorType: error.name}, '*'); window.parent.postMessage({result: "Pass", code: credentials.code}, '*');
} } catch (error) {
window.parent.postMessage({result: "Fail", errorType: error.name}, '*');
}
} }
</script> </script>

View file

@ -0,0 +1,67 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS.supports</title>
<link rel="help" href="https://drafts.csswg.org/css-conditional/#dom-css-supports">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(function() {
assert_equals(CSS.supports("color: red"), true);
}, "Single-argument form allows for declarations without enclosing parentheses");
test(function() {
assert_equals(CSS.supports("(color: red) and (color: blue)"), true);
}, "Complex conditions allowed");
test(function() {
assert_equals(CSS.supports("not (foobar)"), true);
}, "general_enclosed still parses");
test(function() {
assert_equals(CSS.supports("color: something-pointless var(--foo)"), true);
}, "Variable references always parse");
test(function() {
assert_equals(CSS.supports("color: something-pointless(var(--foo))"), true);
}, "Variable references in an unknown function always parse");
test(function() {
assert_equals(CSS.supports("color", "red"), true);
}, "two argument form succeeds for known property");
test(function() {
assert_equals(CSS.supports("unknownproperty", "blah"), false);
}, "two argument form fails for unknown property");
test(function() {
assert_equals(CSS.supports("width", "blah"), false);
}, "two argument form fails for invalid value");
test(function() {
assert_equals(CSS.supports("--foo", "blah"), true);
}, "two argument form succeeds for custom property");
test(function() {
assert_equals(CSS.supports("selector(div)"), true);
}, "selector() function accepts a selector");
test(function() {
assert_equals(CSS.supports("selector(div, div)"), false);
}, "selector() function doesn't accept a selector list");
test(function() {
assert_equals(CSS.supports("selector(::-webkit-unknown-pseudo-element)"), false);
}, "selector() function rejects unknown webkit pseudo-elements.");
test(function() {
assert_equals(CSS.supports("selector(::before)"), true);
}, "selector() function accepts known pseudo-elements");
test(function() {
assert_equals(CSS.supports("selector(div + .c)"), true);
}, "selector() with simple combinators");
test(function() {
assert_equals(CSS.supports("selector(div | .c)"), false);
}, "selector() with unknown combinators");
</script>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1138504">
<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html">
<p>Test passes if there is a filled green square.</p>
<div style="display: grid; grid-template-columns: 100px 100px;">
<div style="min-height: 100px;">
<div style="height: 100%; background: green;"></div>
</div>
<div style="height: 100px;"></div>
</div>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1138504">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; height: 100px; background: red;"></div>
<div style="display: grid; width: 100px; height: 100px;">
<div>
<div style="position: relative; height: 100px; background: green; top: -100%;"></div>
</div>
</div>

View file

@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml"
class="reftest-wait">
<title>Removing a clip-path attribute pointing to an empty &#x3c;clipPath&#x3e;</title>
<h:link rel="help" href="https://drafts.fxtf.org/css-masking-1/#ClipPathElement"/>
<h:link rel="match" href="reference/clip-path-square-003-ref.svg"/>
<h:script src="/common/reftest-wait.js"/>
<h:script src="/common/rendering-utils.js"/>
<clipPath id="empty"/>
<g clip-path='url("#empty")'>
<rect width="200" height="200" fill="green"/>
</g>
<script>
waitForAtLeastOneFrame().then(() => {
document.querySelector('svg > g').removeAttribute('clip-path');
takeScreenshot();
});
</script>
</svg>

After

Width:  |  Height:  |  Size: 731 B

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<title>CSS Masking: Test clip-path nonzero path interpolation with zoom</title>
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-path">
<link rel="match" href="reference/clip-path-path-interpolation-with-zoom-ref.html">
<meta name="assert" content="The clip-path property takes the basic shape
'path()' for clipping. Test the interpolation of nonzero
path function.">
<style>
@keyframes anim {
from {
clip-path: path(nonzero, 'M20,20h60 v60 h-60z M30,30 h40 v40 h-40z');
}
to {
clip-path: path(nonzero, 'M50,50h50 v50 h-50z M20,20 h50 v50 h-50z');
}
}
#rect {
width: 100px;
zoom: 3;
height: 100px;
background-color: green;
animation: anim 10s -5s paused linear;
}
</style>
<div id="rect"></div>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<title>CSS Masking: Test clip-path property hit-testing when the page is zoomed</title>
<link rel="author" title="Noam Rosenthal" href="mailto:noam@webkit.org">
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-path">
<meta name="assert" content="The zoomed path is hit-tested correctly">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
#triangle {
width: 100px;
height: 100px;
background-color: green;
clip-path: path(nonzero, 'M0 0, L100 0, L0 100, L 0 0');
zoom: 2;
}
</style>
<div id="triangle"></div>
<script>
test(() => {
assert_equals(document.elementFromPoint(20, 20).id, 'triangle')
assert_equals(document.elementFromPoint(150, 20).id, 'triangle')
assert_equals(document.elementFromPoint(180, 180).tagName, 'BODY')
}, 'clip-path: path() hit-test takes zoom into account');
</script>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<title>CSS Masking: Test clip-path property when the page is zoomed</title>
<link rel="author" title="Noam Rosenthal" href="mailto:noam@webkit.org">
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-path">
<link rel="match" href="reference/clip-path-path-with-zoom-ref.html">
<meta name="assert" content="The path gets zoomed together with the content">
<style>
#red {
position: absolute;
width: 100px;
height: 100px;
background: red;
}
#rect {
width: 100px;
height: 100px;
background-color: green;
clip-path: path(nonzero, 'M0 0, L100 0, L0 100, L 0 0');
zoom: 2;
}
</style>
<div id="red"></div>
<div id="rect"></div>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<title>CSS Masking: Test clip-path nonzero path interpolation with zoom</title>
<style type="text/css">
#rect {
width: 300px;
height: 300px;
background-color: green;
clip-path: path('M105,105 H270 V270 H105Z M75,75 H210 V210 H75Z');
}
</style>
<div id="rect"></div>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<title>CSS Masking: Test clip-path property when the page is zoomed</title>
<style>
#rect {
width: 200px;
height: 200px;
background: green;
clip-path: path(nonzero, 'M0 0, L200 0, L0 200');
}
</style>
<div id="rect"></div>
</html>

View file

@ -0,0 +1,5 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: Doesn't crash with small but nonzero width/height in ratio</title>
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<div style="aspect-ratio: 1/0.00000000000001"></div>
<div style="aspect-ratio: 0.00000000000001/1"></div>

View file

@ -1,48 +0,0 @@
<!doctype html>
<meta charset="utf-8">
<title>CSSOM - CSS interface</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#the-css.escape()-method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(function () {
// https://drafts.csswg.org/cssom/#dom-css-escape
// https://drafts.csswg.org/cssom/#serialize-an-identifier
assert_equals(CSS.escape("hello world"), "hello\\ world", "CSS.escape: spaces get escaped with backslashes");
assert_equals(CSS.escape("hello\0world"), "hello\u{FFFD}world", "CSS.escape: NULL get replaced with U+FFFD REPLACEMENT CHARACTER");
assert_equals(CSS.escape("hello0world"), "hello0world", "CSS.escape: Numbers within string preserved");
assert_equals(CSS.escape("hello\x10world"), "hello\\10 world", "CSS.escape: Values between \\x01 and \\x1f are unicode escaped");
assert_equals(CSS.escape("hello\\world"), "hello\\\\world", "CSS.escape: Backslashes get backslash-escaped");
assert_equals(CSS.escape("hello\u{1234}world"), "hello\u{1234}world", "CSS.escape: Code points greater than U+0080 are preserved");
assert_equals(CSS.escape("hello\x7Fworld"), "hello\\7f world", "CSS.escape: Some code points less than U+0080 are unicode-escaped");
assert_equals(CSS.escape("-"), "\\-", "CSS.escape: Single dash escaped");
assert_equals(CSS.escape("0foo"), "\\30 foo", "CSS.escape: Numbers at the beginning of an ident get unicode escaped");
assert_equals(CSS.escape("-0foo"), "-\\30 foo", "CSS.escape: Numbers at the beginning of an ident after single hyphen get unicode escaped");
assert_equals(CSS.escape("--0foo"), "--0foo", "CSS.escape: Numbers at the beginning of an ident after multiple hyphens do not get unicode escaped");
}, "CSS.escape");
test(function () {
// https://drafts.csswg.org/css-conditional/#dom-css-supports
// https://drafts.csswg.org/css-conditional/#typedef-supports-condition
assert_equals(CSS.supports("color: red"), true, "CSS.supports: Single-argument form allows for declarations without enclosing parentheses");
assert_equals(CSS.supports("(color: red) and (color: blue)"), true, "CSS.supports: Complex conditions allowed");
assert_equals(CSS.supports("not (foobar)"), true, "CSS.supports: general_enclosed still parses");
assert_equals(CSS.supports("color: something-pointless var(--foo)"), true, "Variable references always parse");
assert_equals(CSS.supports("color: something-pointless(var(--foo))"), true, "Variable references in an unknown function always parse");
}, "CSS.supports, one argument form");
test(function () {
// https://drafts.csswg.org/css-conditional/#dom-css-supports
// https://drafts.csswg.org/css-conditional/#dfn-support
assert_equals(CSS.supports("color", "red"), true, "CSS.supports: two argument form succeeds for known property");
assert_equals(CSS.supports("unknownproperty", "blah"), false, "CSS.supports: two argument form fails for unknown property");
assert_equals(CSS.supports("width", "blah"), false, "CSS.supports: two argument form fails for invalid value");
assert_equals(CSS.supports("--foo", "blah"), true, "CSS.supports: two argument form succeeds for custom property");
}, "CSS.supports, two argument form");
test(function () {
assert_equals(CSS.supports("selector(div)"), true, "CSS.supports: selector() function accepts a selector");
assert_equals(CSS.supports("selector(div, div)"), false, "CSS.supports: selector() function doesn't accept a selector list");
assert_equals(CSS.supports("selector(::-webkit-unknown-pseudo-element)"), false, "CSS.supports: selector() function rejects unknown webkit pseudo-elements.");
assert_equals(CSS.supports("selector(::before)"), true, "CSS.supports: selector() function accepts known pseudo-elements");
assert_equals(CSS.supports("selector(div + .c)"), true, "CSS.supports: selector() with simple combinators");
assert_equals(CSS.supports("selector(div | .c)"), false, "CSS.supports: selector() with unknown combinators");
}, "CSS.supports, selector function");
</script>

View file

@ -85,6 +85,10 @@ test(function() {
assert_equals(CSS.escape('abcdefghijklmnopqrstuvwxyz'), 'abcdefghijklmnopqrstuvwxyz'); assert_equals(CSS.escape('abcdefghijklmnopqrstuvwxyz'), 'abcdefghijklmnopqrstuvwxyz');
assert_equals(CSS.escape('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); assert_equals(CSS.escape('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
assert_equals(CSS.escape("hello\\world"), "hello\\\\world", "Backslashes get backslash-escaped");
assert_equals(CSS.escape("hello\u{1234}world"), "hello\u{1234}world", "Code points greater than U+0080 are preserved");
assert_equals(CSS.escape("-"), "\\-", "CSS.escape: Single dash escaped");
assert_equals(CSS.escape('\x20\x21\x78\x79'), '\\ \\!xy'); assert_equals(CSS.escape('\x20\x21\x78\x79'), '\\ \\!xy');
}, "Various tests"); }, "Various tests");

View file

@ -0,0 +1,117 @@
<html>
<head>
<title>Density corrected size: canvas</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<meta name="assert" content="Assert that density-corrected size in EXIF is taken into account for images when drawn in canvas">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<p>You should see green/yellow gradient boxes</p>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D u_image;
varying vec2 v_texCoord;
uniform float u_frame;
void main(void) {
gl_FragColor = texture2D(u_image, v_texCoord);
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
precision mediump float;
attribute vec2 a_vertex;
attribute vec2 a_tex;
varying vec2 v_texCoord;
void main(void) {
gl_Position = vec4(a_vertex, 0, 1) ;
v_texCoord = a_tex;
}
</script>
<script>
const dim = 3
function drawImage2d(context, image, srcRect) {
context.drawImage(image, ...srcRect, 0, 0, dim, dim)
return context.getImageData(0, 0, dim, dim)
}
function drawImage3d(gl, image, srcRect) {
const vshader = gl.createShader(gl.VERTEX_SHADER)
const fshader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(vshader, document.querySelector("#shader-vs").textContent)
gl.shaderSource(fshader, document.querySelector("#shader-fs").textContent)
gl.compileShader(vshader)
gl.compileShader(fshader)
const program = gl.createProgram()
gl.attachShader(program, vshader)
gl.attachShader(program, fshader)
gl.linkProgram(program)
gl.useProgram(program)
const a_vertex = gl.getAttribLocation(program, "a_vertex")
const a_tex = gl.getAttribLocation(program, "a_tex")
const buf_vertex = gl.createBuffer()
const buf_tex = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, buf_tex)
const [sx, sy, sw, sh] = [srcRect[0] / image.naturalWidth, srcRect[1] / image.naturalHeight, srcRect[2] / image.naturalWidth, srcRect[3] / image.naturalHeight]
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
sx, sy, sx + sw, sy, sx, sy + sh, sx + sw, sy + sh
]), gl.STATIC_DRAW)
gl.bindBuffer(gl.ARRAY_BUFFER, buf_vertex)
var vertices = [-1, 1, 1, 1, -1, -1, 1, -1]
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)
var texture = gl.createTexture()
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
gl.viewport(0, 0, dim, dim)
gl.enableVertexAttribArray(a_vertex)
gl.enableVertexAttribArray(a_tex)
gl.uniform1i(gl.getUniformLocation(program, "u_image"), 0)
gl.bindBuffer(gl.ARRAY_BUFFER, buf_tex)
gl.vertexAttribPointer(a_tex, 2, gl.FLOAT, false, 0, 0)
gl.bindBuffer(gl.ARRAY_BUFFER, buf_vertex)
gl.vertexAttribPointer(a_vertex, 2, gl.FLOAT, false, 0, 0)
gl.clearColor(1, 1, 1, 1)
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
const pixels = new Uint8ClampedArray(dim * dim * 4)
gl.readPixels(0, 0, dim, dim, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
return {data: pixels, width: dim, height: dim}
}
function createCanvasWithImage(src, contextType, srcRect) {
const canvas = document.createElement('canvas')
canvas.width = canvas.height = dim
const image = new Image()
image.src = src
return new Promise(resolve => {
image.onload = () => {
const context = canvas.getContext(contextType)
if (contextType === '2d')
resolve(drawImage2d(context, image, srcRect))
else
resolve(drawImage3d(context, image, srcRect))
}
})
}
async function checkCanvasImage(src, contextType, srcRect, reference) {
const data = await createCanvasWithImage(src, contextType, srcRect)
assert_array_approx_equals(data.data, reference.data, 32)
}
promise_test(async () => {
const reference = await createCanvasWithImage('resources/exif-resolution-none.jpg', '2d', [40, 5, 20, 5]);
await checkCanvasImage("resources/exif-resolution-valid-hires.jpg", '2d', [20, 5, 10, 1], reference)
await checkCanvasImage("resources/exif-resolution-valid-lores.jpg", '2d', [80, 5, 40, 10], reference)
await checkCanvasImage("resources/exif-resolution-none.jpg", 'webgl', [40, 5, 20, 5], reference)
await checkCanvasImage("resources/exif-resolution-valid-hires.jpg", 'webgl', [20, 5, 10, 1], reference)
await checkCanvasImage("resources/exif-resolution-valid-lores.jpg", 'webgl', [80, 5, 40, 1], reference)
})
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<html>
<head>
<title>Density Corrected Size: various elements</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
</head>
<body>
<svg style="width: 800px; height: 800px">
<image xlink:href="resources/exif-resolution-none.jpg" x="0" y="0" width="120" height="120" preserveAspectRatio="xMinYMin meet"></image>
<image xlink:href="resources/exif-resolution-preapplied-lores.jpg" x="200" y="0" width="120" height="120" preserveAspectRatio="xMidYMin meet"></image>
<image xlink:href="resources/exif-resolution-none.jpg" x="400" y="0" width="120" height="120" preserveAspectRatio="xMaxYMin meet"></image>
<image xlink:href="resources/exif-resolution-valid-non-uniform.jpg" x="630" y="0" width="60" height="120" preserveAspectRatio="none"></image>
<image xlink:href="resources/exif-resolution-preapplied-lores.jpg" x="0" y="150" width="120" height="120" preserveAspectRatio="xMinYMid slice"></image>
<image xlink:href="resources/exif-resolution-none.jpg" x="200" y="150" width="120" height="120" preserveAspectRatio="xMidYMid slice"></image>
<image xlink:href="resources/exif-resolution-preapplied-lores.jpg" x="400" y="150" width="120" height="120" preserveAspectRatio="xMaxYMid slice"></image>
<image xlink:href="resources/exif-resolution-preapplied-non-uniform.jpg" x="600" y="150" width="120" height="120" preserveAspectRatio="xMidYMid slice"></image>
<image xlink:href="resources/exif-resolution-none.jpg" x="200" y="300" width="120" height="120" preserveAspectRatio="xMidYMax meet"></image>
<image xlink:href="resources/exif-resolution-preapplied-lores.jpg" x="400" y="300" width="120" height="120" preserveAspectRatio="xMaxYMax meet"></image>
<image xlink:href="resources/exif-resolution-preapplied-non-uniform.jpg" x="600" y="300" width="120" height="120" preserveAspectRatio="xMaxYMid slice"></image>
<image xlink:href="resources/exif-resolution-none.jpg" x="0" y="450" width="120" height="120" preserveAspectRatio="none"></image>
<image xlink:href="resources/exif-resolution-preapplied-lores.jpg" x="200" y="450" width="120" height="120" preserveAspectRatio="none"></image>
<image xlink:href="resources/exif-resolution-preapplied-non-uniform.jpg" x="400" y="450" width="120" height="120" preserveAspectRatio="none"></image>
<image xlink:href="resources/exif-resolution-preapplied-non-uniform.jpg" x="600" y="450" width="120" height="120" preserveAspectRatio="xMaxYMax meet"></image>
</svg>
</div>
</body>
</html>

View file

@ -0,0 +1,32 @@
<html>
<head>
<title>Density Corrected Size: SVG aspect ratio</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<link rel="match" href="density-corrected-image-svg-aspect-ratio-ref.html" />
<meta name="assert" content="Assert that SVG aspect ratio is applied correctly on density-corrected images">
<meta name=fuzzy content="10;100">
</head>
<body>
<svg style="width: 800px; height: 800px">
<image xlink:href="resources/exif-resolution-valid-hires.jpg" x="0" y="0" width="120" height="120" preserveAspectRatio="xMinYMin meet"></image>
<image xlink:href="resources/exif-resolution-valid-lores.jpg" x="200" y="0" width="120" height="120" preserveAspectRatio="xMidYMin meet"></image>
<image xlink:href="resources/exif-resolution-valid-hires.jpg" x="400" y="0" width="120" height="120" preserveAspectRatio="xMaxYMin meet"></image>
<image xlink:href="resources/exif-resolution-valid-non-uniform.jpg" x="600" y="0" width="120" height="120" preserveAspectRatio="xMidYMin meet"></image>
<image xlink:href="resources/exif-resolution-valid-lores.jpg" x="0" y="150" width="120" height="120" preserveAspectRatio="xMinYMid slice"></image>
<image xlink:href="resources/exif-resolution-valid-hires.jpg" x="200" y="150" width="120" height="120" preserveAspectRatio="xMidYMid slice"></image>
<image xlink:href="resources/exif-resolution-valid-lores.jpg" x="400" y="150" width="120" height="120" preserveAspectRatio="xMaxYMid slice"></image>
<image xlink:href="resources/exif-resolution-valid-non-uniform.jpg" x="600" y="150" width="120" height="120" preserveAspectRatio="xMinYMid slice"></image>
<image xlink:href="resources/exif-resolution-valid-hires.jpg" x="200" y="300" width="120" height="120" preserveAspectRatio="xMidYMax meet"></image>
<image xlink:href="resources/exif-resolution-valid-lores.jpg" x="400" y="300" width="120" height="120" preserveAspectRatio="xMaxYMax meet"></image>
<image xlink:href="resources/exif-resolution-valid-non-uniform.jpg" x="600" y="300" width="120" height="120" preserveAspectRatio="xMaxYMid slice"></image>
<image xlink:href="resources/exif-resolution-valid-hires.jpg" x="0" y="450" width="120" height="120" preserveAspectRatio="none"></image>
<image xlink:href="resources/exif-resolution-valid-lores.jpg" x="200" y="450" width="120" height="120" preserveAspectRatio="none"></image>
<image xlink:href="resources/exif-resolution-valid-non-uniform.jpg" x="400" y="450" width="120" height="120" preserveAspectRatio="none"></image>
<image xlink:href="resources/exif-resolution-valid-non-uniform.jpg" x="600" y="450" width="120" height="120" preserveAspectRatio="xMaxYMax meet"></image>
</svg>
</div>
</body>
</html>

View file

@ -0,0 +1,24 @@
<html>
<head>
<title>Density Corrected Size: SVG</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
</head>
<body>
<svg width="200" height="200">
<image href="resources/exif-resolution-none.jpg" />
</svg>
<svg width="200" height="200">
<image href="resources/exif-resolution-none.jpg" preserveAspectRatio="none" width="50" height="25"/>
</svg>
<svg width="200" height="200">
<image href="resources/exif-resolution-none.jpg" preserveAspectRatio="none" width="200" height="100" />
</svg>
<svg width="200" height="200">
<image href="resources/exif-resolution-none.jpg" preserveAspectRatio="none" width="50" height="100" />
</svg>
<svg width="200" height="200" style="transform-origin: 25% 25%; transform: rotate(90deg)">
<image href="resources/exif-resolution-none.jpg" preserveAspectRatio="none" width="200" height="100" />
</svg>
</div>
</body>
</html>

View file

@ -0,0 +1,26 @@
<html>
<head>
<title>Density Corrected Size: SVG</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<link rel="match" href="density-corrected-image-svg-ref.html" />
<meta name="assert" content="Assert that density-corrected size in EXIF is taken into account for SVG <image>">
</head>
<body>
<svg width="200" height="200">
<image href="resources/exif-resolution-none.jpg" />
</svg>
<svg width="200" height="200">
<image href="resources/exif-resolution-valid-hires.jpg" />
</svg>
<svg width="200" height="200">
<image href="resources/exif-resolution-valid-lores.jpg" />
</svg>
<svg width="200" height="200">
<image href="resources/exif-resolution-valid-non-uniform.jpg" />
</svg>
<svg width="200" height="200">
<image href="resources/exif-resolution-with-orientation.jpg" />
</svg>
</div>
</body>
</html>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./third_party/piexif/piexif.js"></script>
<script src="./resources/exify.js"></script>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<script>
async function test_valid(input) {
const image = await createImageWithMetadata(input)
assert_equals(image.naturalWidth, input.preferredWidth)
assert_equals(image.naturalHeight, input.preferredHeight)
}
async function test_invalid(input) {
const image = await createImageWithMetadata(input)
assert_equals(image.naturalWidth, input.width)
assert_equals(image.naturalHeight, input.height)
}
async function test() {
await test_valid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 40, resolutionX: 36, resolutionY: 36, resolutionUnit: 2})
await test_valid({width: 10, height: 20, preferredWidth: 2, preferredHeight: 4, resolutionX: 360, resolutionY: 360, resolutionUnit: 2})
await test_valid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 10, resolutionX: 36, resolutionY: 144, resolutionUnit: 2})
await test_valid({width: 10, height: 20, preferredWidth: 10, preferredHeight: 40, resolutionX: 72, resolutionY: 36, resolutionUnit: 2})
await test_valid({width: 30, height: 30, preferredWidth: 90, preferredHeight: 30, resolutionX: 24, resolutionY: 72, resolutionUnit: 2})
await test_invalid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 30, resolutionX: 36, resolutionY: 36, resolutionUnit: 2})
await test_invalid({width: 10, height: 20, preferredWidth: 33, preferredHeight: 40, resolutionX: 36, resolutionY: 36, resolutionUnit: 2})
await test_invalid({width: 10, height: 20, preferredHeight: 40, resolutionX: 36, resolutionY: 36, resolutionUnit: 2})
await test_invalid({width: 10, height: 20, preferredWidth: 20, resolutionX: 36, resolutionY: 36, resolutionUnit: 2})
await test_invalid({width: 30, height: 30, preferredWidth: 90, preferredHeight: 30, resolutionY: 72, resolutionUnit: 2})
await test_invalid({width: 30, height: 30, preferredWidth: 90, preferredHeight: 30, resolutionX: 24, resolutionUnit: 2})
await test_invalid({width: 30, height: 30, preferredWidth: 90, preferredHeight: 30, resolutionX: 24, resolutionY: 72, resolutionUnit: 1})
await test_invalid({width: 3, height: 3, preferredHeight: 2000000, preferredWidth: 50})
}
promise_test(test)
</script>
</body>
</html>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<head>
<title>Density corrected size: background images</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
</head>
<body>
<style>
body {
--lores: url(resources/exif-resolution-valid-lores.jpg);
--hires: url(resources/exif-resolution-valid-hires.jpg);
--default: url(resources/exif-resolution-none.jpg);
--non-uniform: url(resources/exif-resolution-valid-non-uniform.jpg);
}
.default-bg {background-image: var(--default); }
.lores-bg {background-image: var(--lores); }
.hires-bg {background-image: var(--hires); }
.invalid-bg {background-image: var(--invalid); }
.non-uniform-bg {background-image: var(--non-uniform); }
.box { width: 200px; height: 200px; display: inline-block; }
.tiled {background-repeat: repeat; }
.stretch {background-repeat: no-repeat; background-size: contain; }
</style>
<div class="default-bg tiled box"></div>
<div class="lores-bg tiled box"></div>
<div class="hires-bg tiled box"></div>
<div class="non-uniform-bg tiled box"></div>
<br/>
<div class="lores-bg stretch box"></div>
<div class="default-bg stretch box"></div>
<div class="non-uniform-bg stretch box"></div>
</body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<head>
<title>Density corrected size: background images</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<link rel="match" href="density-corrected-size-bg-ref.html" />
<meta name="assert" content="Assert that background images with EXIF density-corrected-size are rendered correctly">
</head>
<body>
<style>
body {
--lores: url(resources/exif-resolution-valid-lores.jpg);
--hires: url(resources/exif-resolution-valid-hires.jpg);
--default: url(resources/exif-resolution-none.jpg);
--non-uniform: url(resources/exif-resolution-valid-non-uniform.jpg);
}
.default-bg {background-image: var(--default); }
.lores-bg {background-image: var(--lores); }
.hires-bg {background-image: var(--hires); }
.invalid-bg {background-image: var(--invalid); }
.non-uniform-bg {background-image: var(--non-uniform); }
.box { width: 200px; height: 200px; display: inline-block; }
.tiled {background-repeat: repeat; }
.stretch {background-repeat: no-repeat; background-size: contain; }
</style>
<div class="default-bg tiled box"></div>
<div class="lores-bg tiled box"></div>
<div class="hires-bg tiled box"></div>
<div class="non-uniform-bg tiled box"></div>
<br/>
<div class="lores-bg stretch box"></div>
<div class="default-bg stretch box"></div>
<div class="non-uniform-bg stretch box"></div>
</body>
</html>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<body>
<img src="resources/exif-resolution-none.jpg" width="100" height="50" />
<img src="resources/exif-resolution-none.jpg" width="50" height="25" />
<img src="resources/exif-resolution-none.jpg" width="200" height="100"/>
<img src="resources/exif-resolution-none.jpg" width="50" height="100"/>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<head>
<title>Density corrected size: rendering</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<link rel="match" href="density-corrected-size-img-ref.html" />
<meta name="assert" content="Assert that images with EXIF density-corrected-size are rendered correctly">
</head>
<body>
<img src="resources/exif-resolution-none.jpg" />
<img src="resources/exif-resolution-valid-hires.jpg" />
<img src="resources/exif-resolution-valid-lores.jpg" />
<img src="resources/exif-resolution-valid-non-uniform.jpg" />
</body>
</html>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<head>
<title>Density corrected size: pseudo-elements</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
</head>
<body>
<style>
body {
--lores: url(resources/exif-resolution-valid-lores.jpg);
--default: url(resources/exif-resolution-none.jpg);
}
.lores-after::after {content: var(--lores); width: 200px; height: 100px; }
.default-after::after {content: var(--default); }
</style>
<div class="lores-after box"></div>
<div class="default-after box"></div>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<head>
<title>Density corrected size: pseudo-elements</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<link rel="match" href="density-corrected-size-pseudo-elements-ref.html" />
<meta name="assert" content="Assert that images with EXIF density-corrected-size are rendered correctly when in a pseudo element">
</head>
<body>
<style>
body {
--lores: url(resources/exif-resolution-valid-lores.jpg);
--default: url(resources/exif-resolution-none.jpg);
}
.lores-after::after {content: var(--lores); }
.default-after::after {content: var(--default); }
</style>
<div class="lores-after box"></div>
<div class="default-after box"></div>
</body>
</html>

View file

@ -0,0 +1,34 @@
<html>
<head>
<title>Density Corrected Size: various elements</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<style>
.row {
display: flex;
}
.row > * {
object-fit: none;
object-position: top left;
margin: 5px;
width: 100px;
height: 50px;
background: #CCCCCC;
}
</style>
</head>
<body>
<p>There following boxes should be identical (the colorful boxes at the top-left quarter)</p>
<div class="row">
<div>
<img src="resources/exif-resolution-none.jpg" width="50" height="25" />
</div>
<div>
<img src="resources/exif-resolution-none.jpg" width="50" height="25" />
</div>
<div>
<img src="resources/exif-resolution-none.jpg" width="50" height="25" />
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,34 @@
<html>
<head>
<title>Density Corrected Size: various elements</title>
<link rel="author" title="Noam Rosenthal" href="noam@webkit.org">
<link rel="match" href="density-corrected-various-elements-ref.html" />
<meta name="assert" content="Assert that density-corrected size in EXIF is taken into account for images in all relevant elements (input/video-poster)">
<style>
.row {
display: flex;
}
.row > * {
object-fit: none;
object-position: top left;
margin: 5px;
width: 100px;
height: 50px;
background: #CCCCCC;
}
</style>
</head>
<body>
<p>There following boxes should be identical (the colorful boxes at the top-left quarter)</p>
<div class="row">
<div>
<img src="resources/exif-resolution-none.jpg" width="50" height="25" />
</div>
<video poster="resources/exif-resolution-valid-hires.jpg"></video>
<div>
<input type="image" src="resources/exif-resolution-valid-hires.jpg" />
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1,39 @@
function createImageWithMetadata({
width,
height,
preferredWidth,
preferredHeight,
resolutionX,
resolutionY,
resolutionUnit,
orientation
}) {
const canvas = document.createElement('canvas')
canvas.width = width || 100
canvas.height = height || 100
const ctx = canvas.getContext('2d')
ctx.fillColor = 'green'
ctx.fillRect(0, 0, canvas.width, canvas.height)
const original = canvas.toDataURL('image/jpeg')
const root = {}
const exif = {}
if (orientation !== undefined)
root[piexif.ExifIFD.Orientation] = orientation
if (resolutionX !== undefined)
root[piexif.ImageIFD.XResolution] = [resolutionX, 1]
if (resolutionY !== undefined)
root[piexif.ImageIFD.YResolution] = [resolutionY, 1]
if (resolutionUnit !== undefined)
root[piexif.ImageIFD.ResolutionUnit] = resolutionUnit
if (preferredWidth !== undefined)
exif[piexif.ExifIFD.PixelXDimension] = preferredWidth
if (preferredHeight !== undefined)
exif[piexif.ExifIFD.PixelYDimension] = preferredHeight
const exifString = piexif.dump({'0th': root, 'Exif': exif})
const newDataUrl = piexif.insert(exifString, original)
const image = new Image()
image.src = newDataUrl
return new Promise(resolve => {
image.onload = () => resolve(image);
})
}

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Hiroaki Matoba
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<head>
<title>Iframes with loading='lazy' in script disabled iframe are not handled
as 'lazy'</title>
<link rel="help" href="https://github.com/scott-little/lazyload">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<div style="height:1000vh;"></div>
<iframe id="iframe" sandbox="allow-same-origin"
src="resources/iframe-loading-lazy-in-viewport.html">
</iframe>
<script>
promise_test(async t => {
await new Promise(resolve => iframe.addEventListener("load", resolve));
const inner_iframe = iframe.contentDocument.querySelector("iframe");
assert_equals(inner_iframe.contentDocument.body.textContent.trim(), 'Subframe',
"lazy-load iframe shouldn't be honored in script disabled iframe");
});
</script>

View file

@ -0,0 +1,2 @@
<!DOCTYPE html>
<iframe id="iframe" loading="lazy" src="subframe.html"></iframe>

View file

@ -1,11 +1,11 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8" />
<title>Test for PaymentRequest.abort() method</title> <title>Test for PaymentRequest.abort() method</title>
<link rel="help" href="https://w3c.github.io/payment-request/#abort-method"> <link rel="help" href="https://w3c.github.io/payment-request/#abort-method" />
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script> <script src="/resources/testdriver.js"></script>
<script src='/resources/testdriver-vendor.js'></script> <script src="/resources/testdriver-vendor.js"></script>
<script> <script>
"use strict"; "use strict";
setup({ setup({
@ -23,7 +23,7 @@ const applePay = Object.freeze({
countryCode: "US", countryCode: "US",
merchantCapabilities: ["supports3DS"], merchantCapabilities: ["supports3DS"],
supportedNetworks: ["visa"], supportedNetworks: ["visa"],
} },
}); });
const defaultMethods = Object.freeze([basicCard, applePay]); const defaultMethods = Object.freeze([basicCard, applePay]);
const defaultDetails = Object.freeze({ const defaultDetails = Object.freeze({
@ -44,24 +44,22 @@ promise_test(async t => {
promise_test(async t => { promise_test(async t => {
const request = new PaymentRequest(defaultMethods, defaultDetails); const request = new PaymentRequest(defaultMethods, defaultDetails);
const promises = new Set([request.abort(), request.abort(), request.abort()]); const promises = new Set([
request.abort(),
request.abort(),
request.abort(),
]);
assert_equals(promises.size, 3, "Must have three unique objects"); assert_equals(promises.size, 3, "Must have three unique objects");
}, "Calling abort() multiple times is always a new object."); }, "Calling abort() multiple times is always a new object.");
promise_test(async t => { promise_test(async t => {
const request = new PaymentRequest(defaultMethods, defaultDetails); const request = new PaymentRequest(defaultMethods, defaultDetails);
const [abortPromise, acceptPromise] = await test_driver.bless( await test_driver.bless("show payment request");
"show payment request", const acceptPromise = request.show();
() => { await request.abort();
const acceptPromise = request.show()
acceptPromise.catch(() => {}); // no-op, just to silence unhandled rejection in devtools.
const abortPromise = request.abort();
return [abortPromise, acceptPromise];
});
await abortPromise;
await promise_rejects_dom(t, "AbortError", acceptPromise); await promise_rejects_dom(t, "AbortError", acceptPromise);
// As request is now "closed", trying to show it will fail // As request is now "closed", trying to show it will fail
await test_driver.bless("show payment request");
await promise_rejects_dom(t, "InvalidStateError", request.show()); await promise_rejects_dom(t, "InvalidStateError", request.show());
}, "The same request cannot be shown multiple times."); }, "The same request cannot be shown multiple times.");
@ -73,22 +71,21 @@ promise_test(async t => {
await promise_rejects_dom(t, "InvalidStateError", request.abort()); await promise_rejects_dom(t, "InvalidStateError", request.abort());
// The request's state is "created", so let's show it // The request's state is "created", so let's show it
// which changes the state to "interactive.". // which changes the state to "interactive.".
const [abortPromise, acceptPromise] = await test_driver.bless( await test_driver.bless("show payment request");
"show payment request", const acceptPromise = request.show();
() => { // Let's set request the state to "closed" by calling .abort()
const acceptPromise = request.show() await request.abort();
// Let's set request the state to "closed" by calling .abort()
const abortPromise = request.abort();
return [abortPromise, acceptPromise];
});
await abortPromise;
// The request is now "closed", so... // The request is now "closed", so...
await promise_rejects_dom(t, "InvalidStateError", request.abort()); await promise_rejects_dom(t, "InvalidStateError", request.abort());
await promise_rejects_dom(t, "AbortError", acceptPromise); await promise_rejects_dom(t, "AbortError", acceptPromise);
}, "Aborting a request before it is shown doesn't prevent it from being shown later."); }, "Aborting a request before it is shown doesn't prevent it from being shown later.");
</script> </script>
<small> <small>
If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> If you find a buggy test, please
and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> and
tag one of the
<a
href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml"
>suggested reviewers</a
>.
</small> </small>

View file

@ -1,65 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Tests for PaymentRequest.canMakePayment() method</title>
<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
<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>
const basicCard = Object.freeze({ supportedMethods: "basic-card" });
const applePay = Object.freeze({
supportedMethods: "https://apple.com/apple-pay",
data: {
version: 3,
merchantIdentifier: "merchant.com.example",
countryCode: "US",
merchantCapabilities: ["supports3DS"],
supportedNetworks: ["visa"],
}
});
const defaultMethods = Object.freeze([basicCard, applePay]);
const defaultDetails = Object.freeze({
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00",
},
},
});
promise_test(async t => {
// This test might never actually hit its assertion, but that's allowed.
const request = new PaymentRequest(defaultMethods, defaultDetails);
for (let i = 0; i < 1000; i++) {
try {
await request.canMakePayment();
} catch (err) {
assert_equals(
err.name,
"NotAllowedError",
"if it throws, then it must be a NotAllowedError."
);
break;
}
}
for (let i = 0; i < 1000; i++) {
try {
await new PaymentRequest(defaultMethods, defaultDetails).canMakePayment();
} catch (err) {
assert_equals(
err.name,
"NotAllowedError",
"if it throws, then it must be a NotAllowedError."
);
break;
}
}
}, `Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.`);
</script>
<small>
If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
</small>

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8" />
<title>Test for PaymentRequest.show() method</title> <title>Test for PaymentRequest.show() method</title>
<link rel="help" href="https://w3c.github.io/payment-request/#show-method"> <link rel="help" href="https://w3c.github.io/payment-request/#show-method" />
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script> <script src="/resources/testdriver.js"></script>
@ -21,7 +21,7 @@ const defaultMethods = Object.freeze([
countryCode: "US", countryCode: "US",
merchantCapabilities: ["supports3DS"], merchantCapabilities: ["supports3DS"],
supportedNetworks: ["visa"], supportedNetworks: ["visa"],
} },
}, },
]); ]);
@ -35,7 +35,7 @@ const defaultDetails = Object.freeze({
}, },
}); });
promise_test(async t => { promise_test(async (t) => {
const request = new PaymentRequest(defaultMethods, defaultDetails); const request = new PaymentRequest(defaultMethods, defaultDetails);
const acceptPromise = request.show(); const acceptPromise = request.show();
// Abort the request after 2 seconds if it has not rejected. This allows the // Abort the request after 2 seconds if it has not rejected. This allows the
@ -46,62 +46,64 @@ promise_test(async t => {
request.abort(); request.abort();
}, 2000); }, 2000);
await promise_rejects_dom(t, "SecurityError", acceptPromise); await promise_rejects_dom(t, "NotAllowedError", acceptPromise);
}, `Calling show() without being triggered by user interaction throws`); }, `Calling show() without being triggered by user interaction throws`);
promise_test(async t => { promise_test(async (t) => {
const request = new PaymentRequest(defaultMethods, defaultDetails); const request = new PaymentRequest(defaultMethods, defaultDetails);
const [acceptPromise] = await test_driver.bless( await test_driver.bless(
"test: throws if the promise [[state]] is not 'created'", "test: throws if the promise [[state]] is not 'created'"
() => { );
const acceptPromise = request.show(); // Sets state to "interactive" const acceptPromise = request.show(); // Sets state to "interactive"
return [acceptPromise]; // No user activation...
}); await promise_rejects_dom(t, "NotAllowedError", request.show());
// Get user activation
await test_driver.bless(
"test: throws if the promise [[state]] is not 'created'"
);
await promise_rejects_dom(t, "InvalidStateError", request.show()); await promise_rejects_dom(t, "InvalidStateError", request.show());
await request.abort(); await request.abort();
await promise_rejects_dom(t, "AbortError", acceptPromise); await promise_rejects_dom(t, "AbortError", acceptPromise);
}, "Throws if the promise [[state]] is not 'created'."); }, "Throws if the promise [[state]] is not 'created'.");
promise_test(async t => { promise_test(async (t) => {
const request1 = new PaymentRequest(defaultMethods, defaultDetails); const request1 = new PaymentRequest(defaultMethods, defaultDetails);
const request2 = new PaymentRequest(defaultMethods, defaultDetails); const request2 = new PaymentRequest(defaultMethods, defaultDetails);
const [acceptPromise1] = await test_driver.bless(
`test: reject promise with "AbortedError" if payment request is already showing`, await test_driver.bless("payment request");
async () => { const acceptPromise1 = request1.show();
const acceptPromise1 = request1.show();
const acceptPromise2 = request2.show(); // User activation consumed, so...
await promise_rejects_dom(t, "AbortError", acceptPromise2); await promise_rejects_dom(t, "NotAllowedError", request2.show());
return [acceptPromise1];
}); // Payment request already showing, so...
await test_driver.bless("payment request");
await promise_rejects_dom(t, "AbortError", request2.show());
await request1.abort(); await request1.abort();
await promise_rejects_dom(t, "AbortError", acceptPromise1); await promise_rejects_dom(t, "AbortError", acceptPromise1);
}, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`); }, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`);
promise_test(async t => { promise_test(async (t) => {
const request = new PaymentRequest( const request = new PaymentRequest(
[{ supportedMethods: "this-is-not-supported" }], [{ supportedMethods: "this-is-not-supported" }],
defaultDetails defaultDetails
); );
const [acceptPromise] = await test_driver.bless( await test_driver.bless(`test: reject promise with "NotSupportedError"`);
`test: reject promise with "NotSupportedError"`, const acceptPromise = request.show();
() => {
const acceptPromise = request.show();
return [acceptPromise];
});
await promise_rejects_dom(t, "NotSupportedError", acceptPromise); await promise_rejects_dom(t, "NotSupportedError", acceptPromise);
}, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`); }, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`);
promise_test(async t => { promise_test(async (t) => {
const request = new PaymentRequest(defaultMethods, defaultDetails); const request = new PaymentRequest(defaultMethods, defaultDetails);
const [p1, p2, p3] = await test_driver.bless( await test_driver.bless("call show()");
`test: calling show() multiple times always returns a new promise`, const p1 = request.show();
() => { await test_driver.bless("call show()");
const p1 = request.show(); const p2 = request.show();
const p2 = request.show(); await test_driver.bless("call show()");
const p3 = request.show(); const p3 = request.show();
return [p1, p2, p3];
});
const promises = new Set([p1, p2, p3]); const promises = new Set([p1, p2, p3]);
assert_equals(promises.size, 3, "Must have three unique objects"); assert_equals(promises.size, 3, "Must have three unique objects");
@ -111,9 +113,13 @@ promise_test(async t => {
await request.abort(); await request.abort();
await promise_rejects_dom(t, "AbortError", p1); await promise_rejects_dom(t, "AbortError", p1);
}, "Calling show() multiple times always returns a new promise."); }, "Calling show() multiple times always returns a new promise.");
</script> </script>
<small> <small>
If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> If you find a buggy test, please
and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> and
tag one of the
<a
href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml"
>suggested reviewers</a
>.
</small> </small>

View file

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>show() consumes user activation</title>
<link rel="help" href="https://w3c.github.io/payment-request/#show-method" />
<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>
</head>
<body>
<script>
const defaultMethods = [
{ supportedMethods: "basic-card" },
{
supportedMethods: "https://apple.com/apple-pay",
data: {
version: 3,
merchantIdentifier: "merchant.com.example",
countryCode: "US",
merchantCapabilities: ["supports3DS"],
supportedNetworks: ["visa"],
},
},
];
const defaultDetails = {
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00",
},
},
};
promise_test(async t => {
const pr = new PaymentRequest(defaultMethods, defaultDetails);
// Not activated by user gesture, so not allowed!
await promise_rejects_dom(t, "NotAllowedError", pr.show());
await test_driver.bless("Calls show() method");
// Activated by user gesture, so all good.
const showPromise = pr.show();
// The activation has been consumed, so calling show() again would require
// a new gesture.
await promise_rejects_dom(t, "NotAllowedError", pr.show());
// Abort the payment request
pr.abort()
await promise_rejects_dom(t, "AbortError", showPromise);
}, "Calling share consumes user activation");
</script>
</body>
</html>

View file

@ -1,15 +1,18 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8" />
<title>Test for PaymentRequest.show(optional detailsPromise) method</title> <title>Test for PaymentRequest.show(optional detailsPromise) method</title>
<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method"> <link
rel="help"
href="https://w3c.github.io/browser-payment-api/#show-method"
/>
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script> <script>
// See function testBadUpdate() for test details! // See function testBadUpdate() for test details!
setup({ setup({
allow_uncaught_exception: true, allow_uncaught_exception: true,
explicit_done: true,
explicit_timeout: true,
}); });
// == TEST DATA === // == TEST DATA ===
@ -30,7 +33,7 @@
countryCode: "US", countryCode: "US",
merchantCapabilities: ["supports3DS"], merchantCapabilities: ["supports3DS"],
supportedNetworks: ["visa"], supportedNetworks: ["visa"],
} },
}); });
// Methods // Methods
@ -149,7 +152,7 @@
Object.freeze(recursiveData); Object.freeze(recursiveData);
const modifierWithRecursiveData = Object.freeze({ const modifierWithRecursiveData = Object.freeze({
supportedMethods: validMethodBasicCard, supportedMethods: "basic-card",
total: validTotal, total: validTotal,
data: recursiveData, data: recursiveData,
}); });
@ -160,20 +163,19 @@
The `badDetails` cause detailsPromise to reject with `expectedError`. The `badDetails` cause detailsPromise to reject with `expectedError`.
*/ */
function testBadUpdate(testAssertion, badDetails, expectedError) { function testBadUpdate(testAssertion, badDetails, expectedError) {
promise_test(async t => { promise_test(async (t) => {
const request = new PaymentRequest( const request = new PaymentRequest(
validMethods, validMethods,
validDetails, validDetails,
validOptions validOptions
); );
await test_driver.bless("Payment request");
const detailsPromise = Promise.resolve(badDetails); const detailsPromise = Promise.resolve(badDetails);
const acceptPromise = request.show(detailsPromise); const acceptPromise = request.show(detailsPromise);
let test_func; const test_func =
if (typeof expectedError == "function") { typeof expectedError == "function"
test_func = promise_rejects_js; ? promise_rejects_js
} else { : promise_rejects_dom;
test_func = promise_rejects_dom;
}
await test_func( await test_func(
t, t,
expectedError, expectedError,
@ -182,113 +184,70 @@
); );
}, testAssertion); }, testAssertion);
} }
</script>
<h2>
PaymentRequest <code>.show(optional detailsPromise)</code> tests
</h2>
<h3>
Bad details - causes `detailsPromise` to reject.
</h3>
<p>
Click on each button in sequence from top to bottom without refreshing the page.
No payment sheet should be shown, as all provided values cause an error.
</p>
<p>
<strong>
If you see a payment sheet, it means the test has failed.
</strong>
</p>
<ol>
<li><button onclick="
const rejectedPromise = Promise.reject(new SyntaxError('test'))
.catch(err => err);
testBadUpdate(this.textContent, rejectedPromise, 'AbortError');
">
Rejection of detailsPromise must abort the update with an 'AbortError' DOMException.
</button></li>
<li><button onclick=" const rejectedPromise = Promise.reject(new SyntaxError("test"));
const invalidDetails = { total: `this will cause a TypeError!` }; testBadUpdate(
testBadUpdate(this.textContent, invalidDetails, TypeError); "Rejection of detailsPromise must abort the update with an 'AbortError' DOMException.",
"> rejectedPromise,
Total in the update is a string, so converting to IDL must abort the update with a TypeError. "AbortError"
</button></li> );
<li><button onclick=" testBadUpdate(
const invalidDetails = { total: recursiveData }; "Total in the update is a string, so converting to IDL must abort the update with a TypeError.",
testBadUpdate(this.textContent, invalidDetails, TypeError); { total: `this will cause a TypeError!` },
"> TypeError
Total is recursive, so converting to IDL must abort the update with a TypeError. );
</button></li>
<li><button onclick=" testBadUpdate(
testBadUpdate(this.textContent, invalidDetailsNegativeTotal, TypeError); "Total is recursive, so converting to IDL must abort the update with a TypeError.",
"> { total: recursiveData },
Updating with a negative total results in a TypeError. TypeError
</button></li> );
<li><button onclick=" testBadUpdate(
const badDetails = Object.assign({}, validDetails, { "Updating with a negative total results in a TypeError.",
displayItems: invalidPaymentItems invalidDetailsNegativeTotal,
}); TypeError
testBadUpdate(this.textContent, badDetails, RangeError); );
">
Updating with a displayItem with an invalid currency results in RangeError.
</button></li>
<li><button onclick=" testBadUpdate(
const duplicateShippingOptions = [validShippingOption, validShippingOption]; "Updating with a displayItem with an invalid currency results in RangeError.",
const badDetails = Object.assign({}, validDetails, { { ...validDetails, displayItems: invalidPaymentItems },
shippingOptions: duplicateShippingOptions, RangeError
}); );
testBadUpdate(this.textContent, badDetails, TypeError);
">
Updating with duplicate shippingOptions (same IDs) results in a TypeError.
</button></li>
<li><button onclick="
const badDetails = Object.assign({}, validDetails, {
shippingOptions: invalidShippingOptions,
});
testBadUpdate(this.textContent, badDetails, RangeError);
">
Updating with a shippingOption with an invalid currency value results in a RangError.
</button></li>
<li><button onclick=" testBadUpdate(
// validModifier is there as to avoid false positives "Updating with duplicate shippingOptions (same IDs) results in a TypeError.",
const badModifiers = { modifiers: [modifierWithInvalidTotal, validModifier] }; {
const badDetails = Object.assign({}, validDetails, badModifiers); ...validDetails,
testBadUpdate(this.textContent, badDetails, RangeError); shippingOptions: [validShippingOption, validShippingOption],
"> },
Must throw a RangeError when a modifier's total item has an invalid currency. TypeError
</button></li> );
<li><button onclick=" testBadUpdate(
// validModifier is there as to avoid false positives "Updating with a shippingOption with an invalid currency value results in a RangError.",
const badModifiers = { { ...validDetails, shippingOptions: invalidShippingOptions },
RangeError
);
testBadUpdate(
"Must throw a RangeError when a modifier's total item has an invalid currency.",
{ ...validDetails, modifiers: [modifierWithInvalidTotal, validModifier] },
RangeError
);
testBadUpdate(
"Must throw a RangeError when a modifier display item has an invalid currency.",
{
...validDetails,
modifiers: [modifierWithInvalidDisplayItems, validModifier], modifiers: [modifierWithInvalidDisplayItems, validModifier],
}; },
const badDetails = Object.assign({}, validDetails, badModifiers); RangeError
testBadUpdate(this.textContent, badDetails, RangeError); );
"> testBadUpdate(
Must throw a RangeError when a modifier display item has an invalid currency. "Must throw as Modifier has a recursive dictionary.",
</button></li> { ...validDetails, modifiers: [modifierWithRecursiveData, validModifier] },
TypeError
<li><button onclick=" );
// validModifier is there as to avoid false positives </script>
const badModifiers = {
modifiers: [modifierWithRecursiveData, validModifier],
};
const badDetails = Object.assign({}, validDetails, badModifiers);
testBadUpdate(this.textContent, badDetails, TypeError);
">
Must throw as Modifier has a recursive dictionary.
</button></li>
<li><button onclick="done();">Done!</button></li>
</ol>
<small>
If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
</small>

View file

@ -1,51 +0,0 @@
'use strict';
const SmsProvider = (() => {
class MockWebOTPService {
constructor() {
this.mojoReceiver_ = new blink.mojom.WebOTPServiceReceiver(this);
this.interceptor_ =
new MojoInterfaceInterceptor(blink.mojom.WebOTPService.$interfaceName);
this.interceptor_.oninterfacerequest = (e) => {
this.mojoReceiver_.$.bindHandle(e.handle);
}
this.interceptor_.start();
this.returnValues_ = {};
}
async receive() {
let call = this.returnValues_.receive ?
this.returnValues_.receive.shift() : null;
if (!call)
return;
return call();
}
async abort() {};
pushReturnValuesForTesting(callName, value) {
this.returnValues_[callName] = this.returnValues_[callName] || [];
this.returnValues_[callName].push(value);
return this;
}
}
const mockWebOTPService = new MockWebOTPService();
class SmsProviderChromium {
constructor() {
Object.freeze(this); // Make it immutable.
}
pushReturnValuesForTesting(callName, callback) {
mockWebOTPService.pushReturnValuesForTesting(callName, callback);
}
}
return SmsProviderChromium;
})();

View file

@ -0,0 +1,5 @@
/* Whether the browser is Chromium-based with MojoJS enabled */
export const isChromiumBased = 'MojoInterfaceInterceptor' in self;
/* Whether the browser is WebKit-based with internal test-only API enabled */
export const isWebKitBased = !isChromiumBased && 'internals' in self;

Some files were not shown because too many files have changed in this diff Show more