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
|
@ -0,0 +1,4 @@
|
|||
[interface-prototype-constructor-set-receiver.html]
|
||||
[Window, Location, Navigator, HTMLDocument, and HTMLHeadElement]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[CaretPosition-001.html]
|
||||
[Element at (400, 100)]
|
||||
expected: FAIL
|
||||
|
|
@ -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
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[matchMedia-display-none-iframe.html]
|
||||
expected: ERROR
|
|
@ -312,9 +312,6 @@
|
|||
[Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK]
|
||||
expected: NOTRUN
|
||||
|
||||
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -324,18 +321,12 @@
|
|||
[<iframe>: separate response Content-Type: text/html */*]
|
||||
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]
|
||||
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
|
||||
|
||||
|
|
|
@ -56,3 +56,6 @@
|
|||
[separate text/javascript x/x]
|
||||
expected: FAIL
|
||||
|
||||
[separate text/javascript ]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -11,3 +11,6 @@
|
|||
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
|
||||
expected: FAIL
|
||||
|
||||
[X-Content-Type-Options%3A%20%22nosniFF%22]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[traverse_the_history_5.html]
|
||||
[Multiple history traversals, last would be aborted]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[cross-origin-objects-on-new-window.html]
|
||||
expected: TIMEOUT
|
|
@ -4,14 +4,14 @@
|
|||
expected: FAIL
|
||||
|
||||
[Host element with delegatesFocus including no focusable descendants should be skipped]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
[Element with tabindex should support autofocus]
|
||||
expected: FAIL
|
||||
|
||||
[Area element should support autofocus]
|
||||
expected: TIMEOUT
|
||||
expected: NOTRUN
|
||||
|
||||
[Host element with delegatesFocus should support autofocus]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -171,6 +171,3 @@
|
|||
[XHTML img usemap="#hash-id"]
|
||||
expected: FAIL
|
||||
|
||||
[HTML (standards) IMG usemap="no-hash-name"]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[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]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[iframe_sandbox_popups_nonescaping-1.html]
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
||||
expected: NOTRUN
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[iframe_sandbox_popups_nonescaping-2.html]
|
||||
expected: CRASH
|
||||
expected: TIMEOUT
|
||||
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
[iframe_sandbox_popups_nonescaping-3.html]
|
||||
expected: TIMEOUT
|
||||
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[form-double-submit.html]
|
||||
[default submit action should supersede onclick submit()]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[module-static-import-delayed.html]
|
||||
[document.write in an imported module]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[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)]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
[promise-job-entry.html]
|
||||
expected: TIMEOUT
|
||||
[Fulfillment handler on fulfilled promise]
|
||||
expected: FAIL
|
||||
|
||||
[Rejection handler on pending-then-rejected promise]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[Sanity check: this all works as expected with no promises involved]
|
||||
expected: FAIL
|
||||
|
@ -16,5 +15,5 @@
|
|||
expected: FAIL
|
||||
|
||||
[Fulfillment handler on pending-then-fulfilled promise]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -140,3 +140,12 @@
|
|||
[X SNR (-301.35690681171843 dB) is not greater than or equal to 85.58. Got -301.35690681171843.]
|
||||
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
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
[018.html]
|
||||
expected: TIMEOUT
|
||||
[origin of the script that invoked the method, javascript:]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[Worker-constructor.html]
|
||||
expected: ERROR
|
|
@ -413,6 +413,15 @@
|
|||
}
|
||||
},
|
||||
"css-sizing": {
|
||||
"aspect-ratio": {
|
||||
"small-aspect-ratio-crash.html": [
|
||||
"07712542f179c5e83cc44f4f15130c48e030d8c0",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
]
|
||||
},
|
||||
"frameset-intrinsic-crash.html": [
|
||||
"ab9c43ee44d6c838597074152e1a7463644d29b1",
|
||||
[
|
||||
|
@ -18280,13 +18289,6 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"show-method-optional-promise-rejects-manual.https.html": [
|
||||
"1a322452eb6114630b2f0d1d2a9762092ad5ebb9",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"show-method-optional-promise-resolves-manual.https.html": [
|
||||
"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": [
|
||||
"5e196c82c64bb52ee5b445b664eb5bc0dbd60573",
|
||||
[
|
||||
|
@ -152234,6 +152249,19 @@
|
|||
]
|
||||
]
|
||||
},
|
||||
"relative-grandchild.html": [
|
||||
"9c1b7d54e1f568e13e656a3bc57a840cdc93bcf2",
|
||||
[
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/css/reference/ref-filled-green-100px-square.xht",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"subgrid": {
|
||||
"abs-pos-001.html": [
|
||||
"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": [
|
||||
"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": [
|
||||
"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": {
|
||||
"font-display": {
|
||||
"override-to-optional.tentative.html": [
|
||||
|
@ -279593,6 +279756,16 @@
|
|||
[]
|
||||
]
|
||||
},
|
||||
"cors-rfc1918": {
|
||||
"META.yml": [
|
||||
"7f0d420a0e6f040497827a1cf19cb7b39d55922a",
|
||||
[]
|
||||
],
|
||||
"README.md": [
|
||||
"f641b61971e8b09de644476d2e04a1e45890b633",
|
||||
[]
|
||||
]
|
||||
},
|
||||
"credential-management": {
|
||||
"META.yml": [
|
||||
"7b1860921312cc9d9934aa803e3f639df21423a0",
|
||||
|
@ -279612,11 +279785,11 @@
|
|||
[]
|
||||
],
|
||||
"otpcredential-helper.js": [
|
||||
"0c6ce8b1f38ca321900efae35a53977da9370acb",
|
||||
"e07e9f5be359e9173b6c916d91d8ce1f87260885",
|
||||
[]
|
||||
],
|
||||
"otpcredential-iframe.html": [
|
||||
"83f25d573c8ecc967635bb9239a3d0c0c1544d37",
|
||||
"4affc00ecde9951aa2911a7e818615600f324d8f",
|
||||
[]
|
||||
],
|
||||
"passwordcredential-get.html": [
|
||||
|
@ -311165,6 +311338,14 @@
|
|||
"567764a30124c2bc8821a508e2a7f8b6f0787c7e",
|
||||
[]
|
||||
],
|
||||
"clip-path-path-interpolation-with-zoom-ref.html": [
|
||||
"7e0d2a54266f3855dbc8e8e87167a06ea0cc323b",
|
||||
[]
|
||||
],
|
||||
"clip-path-path-with-zoom-ref.html": [
|
||||
"ef91c619c40615f633c64d59bfe302fcfbd8c5fb",
|
||||
[]
|
||||
],
|
||||
"clip-path-rectangle-border-ref.html": [
|
||||
"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": {
|
||||
"META.yml": [
|
||||
"b8dd4761adff3e18b6552d4a8f02abdcd30a3ea6",
|
||||
|
@ -343776,6 +344033,10 @@
|
|||
[]
|
||||
],
|
||||
"resources": {
|
||||
"iframe-loading-lazy-in-viewport.html": [
|
||||
"1efd2bd056dde80de03448a76b9bd28f94fd1795",
|
||||
[]
|
||||
],
|
||||
"subframe.html": [
|
||||
"07cb999afaefe344a0f8d5ac2b792b60abcd22b4",
|
||||
[]
|
||||
|
@ -353543,10 +353804,6 @@
|
|||
"6805c323df5a975231648b830e33ce183c3cbbd3",
|
||||
[]
|
||||
],
|
||||
"mock-sms-receiver.js": [
|
||||
"903456d6830481cfd8d977120105359d4fc43774",
|
||||
[]
|
||||
],
|
||||
"mock-textdetection.js": [
|
||||
"427ce38da21a9cd00e11aab313708f2719d8b094",
|
||||
[]
|
||||
|
@ -353772,7 +354029,7 @@
|
|||
[]
|
||||
],
|
||||
"no-title.html": [
|
||||
"3458af4459674c89de7529aecbc6a0b6de233757",
|
||||
"ae1333a0f7f890b1b5e44a8a5ef3116fd4f5885b",
|
||||
[]
|
||||
],
|
||||
"order.html": [
|
||||
|
@ -354020,7 +354277,7 @@
|
|||
}
|
||||
},
|
||||
"tox.ini": [
|
||||
"a7a02e4b93bdc009ef0b05cbc039c3977fcdd46e",
|
||||
"c38b9f2749c8c0f8b5820ca3c621e396d4a14c7e",
|
||||
[]
|
||||
],
|
||||
"variants.js": [
|
||||
|
@ -354040,6 +354297,14 @@
|
|||
"5e8f640c6659d176eaca4c71cc1798b7285540b7",
|
||||
[]
|
||||
],
|
||||
"test-only-api.m.js": [
|
||||
"984f635abac00272304c78f2f5bb99b397b27523",
|
||||
[]
|
||||
],
|
||||
"test-only-api.m.js.headers": [
|
||||
"5e8f640c6659d176eaca4c71cc1798b7285540b7",
|
||||
[]
|
||||
],
|
||||
"testdriver-actions.js": [
|
||||
"f3e6388e8acd1998d89750150e0779df327a5417",
|
||||
[]
|
||||
|
@ -354061,7 +354326,7 @@
|
|||
[]
|
||||
],
|
||||
"testharness.js": [
|
||||
"85ffcf726af1b634a9e5bc1fc35aca56deb74b4c",
|
||||
"4fb8cea0bcc167c99448c5b680276ebb1413cb5e",
|
||||
[]
|
||||
],
|
||||
"testharness.js.headers": [
|
||||
|
@ -358474,7 +358739,7 @@
|
|||
[]
|
||||
],
|
||||
"epochs_update.sh": [
|
||||
"f460814c962076b4ec72c072dff09925427c90a6",
|
||||
"1c7edf15aaf8c47638393291de1724e41bab8a2d",
|
||||
[]
|
||||
],
|
||||
"jobs.py": [
|
||||
|
@ -365282,7 +365547,7 @@
|
|||
[]
|
||||
],
|
||||
"chrome.py": [
|
||||
"486070ad86d451e73f0e56ce720134024ffc1121",
|
||||
"fd251a431c306f3bb3b12b848f548d8eff07a466",
|
||||
[]
|
||||
],
|
||||
"chrome_android.py": [
|
||||
|
@ -383963,6 +384228,13 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"interface-prototype-constructor-set-receiver.html": [
|
||||
"20f33f243abeef901357fb2026f0fe2182277673",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"interface-prototype-object.html": [
|
||||
"d2d43eda9a94688ffd707a3ed8f89c28e74324c4",
|
||||
[
|
||||
|
@ -396144,7 +396416,7 @@
|
|||
]
|
||||
],
|
||||
"otpcredential-get-basics.https.html": [
|
||||
"edeb42a0f579209c1556d83c7fa98de08757f0dc",
|
||||
"c0cac166de91c242a16bd4d6fc2edfa93aa37680",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
|
@ -399462,6 +399734,13 @@
|
|||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"CSS-supports.html": [
|
||||
"dbe9506de149be2fbb1e28d1b334dbdd5dcbbbe6",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
]
|
||||
},
|
||||
"test_group_insertRule.html": [
|
||||
|
@ -406693,6 +406972,13 @@
|
|||
]
|
||||
},
|
||||
"clip-path": {
|
||||
"clip-path-path-with-zoom-hittest.html": [
|
||||
"30ceefcbc03980564136ad29b6fd1a8f9a318d38",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"interpolation.html": [
|
||||
"da3981feed6ed681ee4a7d88b7ecd167b9fd5c7b",
|
||||
[
|
||||
|
@ -419245,13 +419531,6 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"CSS.html": [
|
||||
"ba048c58acaac5cd2550fb21cb9b6e9ee8fb0bb1",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"CSSCounterStyleRule.html": [
|
||||
"afae84b0b25f4aebf2461179cf5a5a2b769cce4f",
|
||||
[
|
||||
|
@ -419715,7 +419994,7 @@
|
|||
]
|
||||
],
|
||||
"escape.html": [
|
||||
"721c6ea35572d42e2782d6f40f7e73539df35b3a",
|
||||
"895da59c49c0495514f0002fa6c340059c1d3123",
|
||||
[
|
||||
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": {
|
||||
"idlharness.any.js": [
|
||||
"720bacfa3ff3f00e2b8dcc4e061924d2dc48e876",
|
||||
|
@ -473629,6 +473924,13 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"iframe-loading-lazy-in-script-disabled-iframe.html": [
|
||||
"4f191cd7842675d763079911fe9f8b80bd447506",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"iframe-loading-lazy-load-event.html": [
|
||||
"bf98bf7585cf608e6ebb46d025663e22bce8324c",
|
||||
[
|
||||
|
@ -489968,6 +490270,13 @@
|
|||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"onmerchantvalidation-attribute.https.html": [
|
||||
"d31ac2dd72abcf51a28ecec850400f5f0c6b9bb5",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
]
|
||||
},
|
||||
"mimesniff": {
|
||||
|
@ -496499,13 +496808,6 @@
|
|||
}
|
||||
]
|
||||
],
|
||||
"onmerchantvalidation-attribute.https.html": [
|
||||
"d31ac2dd72abcf51a28ecec850400f5f0c6b9bb5",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"onpaymentmethodchange-attribute.https.html": [
|
||||
"f641bec4aa91d8be4f1801869eb699ca4bad03a0",
|
||||
[
|
||||
|
@ -496524,16 +496826,7 @@
|
|||
]
|
||||
],
|
||||
"payment-request-abort-method.https.html": [
|
||||
"8230e2458aaa3e0364dc45985f596759f009547d",
|
||||
[
|
||||
null,
|
||||
{
|
||||
"testdriver": true
|
||||
}
|
||||
]
|
||||
],
|
||||
"payment-request-canmakepayment-method-protection.https.html": [
|
||||
"9c068dfe001e35d57783a0e99f3d6edd50cc5795",
|
||||
"32b87970b4df49d2eef4945e3869f4abfcaa537a",
|
||||
[
|
||||
null,
|
||||
{
|
||||
|
@ -496655,7 +496948,7 @@
|
|||
]
|
||||
],
|
||||
"payment-request-show-method.https.html": [
|
||||
"20d5bab0d14b79fb3dcf3e82e08dc495d038a33d",
|
||||
"e5ee5eed01b26c872d01f801bb0739f791b5be58",
|
||||
[
|
||||
null,
|
||||
{
|
||||
|
@ -496681,11 +496974,22 @@
|
|||
}
|
||||
]
|
||||
],
|
||||
"secure-payment-confirmation.https.html": [
|
||||
"1cc12d49eba1369d57512a52de30eab4fa477da2",
|
||||
"show-consume-activation.https.html": [
|
||||
"0b92c4c15cf158457a9cfae6fab02171a49ca5f2",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
{
|
||||
"testdriver": true
|
||||
}
|
||||
]
|
||||
],
|
||||
"show-method-optional-promise-rejects.https.html": [
|
||||
"3b42965503922d88213409dc814300c05b3a672f",
|
||||
[
|
||||
null,
|
||||
{
|
||||
"testdriver": true
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
|
@ -511065,7 +511369,7 @@
|
|||
]
|
||||
],
|
||||
"element-based-offset-clamp.html": [
|
||||
"b140507493848688f38021573643ce7d6321e514",
|
||||
"6467af199f10224e16f07badf16b73593270f14c",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
|
@ -511353,6 +511657,15 @@
|
|||
]
|
||||
]
|
||||
},
|
||||
"secure-payment-confirmation": {
|
||||
"secure-payment-confirmation.tenative.https.html": [
|
||||
"1cc12d49eba1369d57512a52de30eab4fa477da2",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
]
|
||||
},
|
||||
"selection": {
|
||||
"Document-open.html": [
|
||||
"9e3cb28124c0d65f61d1e71672c2429a3b64a792",
|
||||
|
@ -526952,7 +527265,7 @@
|
|||
]
|
||||
],
|
||||
"urlsearchparams-constructor.any.js": [
|
||||
"1135d5d3dbbfa3625391e090985231c41e88f2c6",
|
||||
"f9878373e5e067598054df4682652a0e9ced270a",
|
||||
[
|
||||
"url/urlsearchparams-constructor.any.html",
|
||||
{}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[interface-prototype-constructor-set-receiver.html]
|
||||
[Window, Location, Navigator, HTMLDocument, and HTMLHeadElement]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[CaretPosition-001.html]
|
||||
[Element at (400, 100)]
|
||||
expected: FAIL
|
||||
|
|
@ -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
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[matchMedia-display-none-iframe.html]
|
||||
expected: ERROR
|
|
@ -312,9 +312,6 @@
|
|||
[fetch(): separate response Content-Type: text/plain ]
|
||||
expected: NOTRUN
|
||||
|
||||
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -324,18 +321,12 @@
|
|||
[<iframe>: separate response Content-Type: text/html */*]
|
||||
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]
|
||||
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
|
||||
|
||||
|
|
|
@ -56,3 +56,6 @@
|
|||
[separate text/javascript x/x]
|
||||
expected: FAIL
|
||||
|
||||
[separate text/javascript ]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -11,3 +11,6 @@
|
|||
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
|
||||
expected: FAIL
|
||||
|
||||
[X-Content-Type-Options%3A%20%22nosniFF%22]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[traverse_the_history_5.html]
|
||||
[Multiple history traversals, last would be aborted]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[cross-origin-objects-on-new-window.html]
|
||||
expected: TIMEOUT
|
|
@ -7,11 +7,11 @@
|
|||
expected: FAIL
|
||||
|
||||
[Host element with delegatesFocus including no focusable descendants should be skipped]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
[Area element should support autofocus]
|
||||
expected: TIMEOUT
|
||||
expected: NOTRUN
|
||||
|
||||
[Host element with delegatesFocus should support autofocus]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -172,6 +172,3 @@
|
|||
[XHTML img usemap="http://example.org/#garbage-before-hash-id"]
|
||||
expected: FAIL
|
||||
|
||||
[HTML (standards) IMG usemap="no-hash-name"]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[iframe_sandbox_popups_escaping-3.html]
|
||||
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]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[iframe_sandbox_popups_nonescaping-1.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
expected: CRASH
|
||||
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
||||
expected: NOTRUN
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[iframe_sandbox_popups_nonescaping-2.html]
|
||||
type: testharness
|
||||
expected: CRASH
|
||||
expected: TIMEOUT
|
||||
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
[iframe_sandbox_popups_nonescaping-3.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[form-double-submit.html]
|
||||
[default submit action should supersede onclick submit()]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[module-static-import-delayed.html]
|
||||
[document.write in an imported module]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[ignore-opens-during-unload.window.html]
|
||||
expected: CRASH
|
||||
expected: TIMEOUT
|
||||
[ignore-opens-during-unload]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
[promise-job-entry.html]
|
||||
expected: TIMEOUT
|
||||
[Fulfillment handler on fulfilled promise]
|
||||
expected: FAIL
|
||||
|
||||
[Rejection handler on pending-then-rejected promise]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[Sanity check: this all works as expected with no promises involved]
|
||||
expected: FAIL
|
||||
|
@ -16,5 +15,5 @@
|
|||
expected: FAIL
|
||||
|
||||
[Fulfillment handler on pending-then-fulfilled promise]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -371,3 +371,9 @@
|
|||
[X SNR (-301.35690681171843 dB) is not greater than or equal to 85.58. Got -301.35690681171843.]
|
||||
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
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
[018.html]
|
||||
expected: TIMEOUT
|
||||
[origin of the script that invoked the method, javascript:]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[Worker-constructor.html]
|
||||
expected: ERROR
|
|
@ -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>
|
5
tests/wpt/web-platform-tests/cors-rfc1918/META.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
spec: https://wicg.github.io/cors-rfc1918/
|
||||
suggested_reviewers:
|
||||
- letitz
|
||||
- camillelamy
|
||||
- mikewest
|
8
tests/wpt/web-platform-tests/cors-rfc1918/README.md
Normal 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/
|
|
@ -3,15 +3,12 @@
|
|||
<title>Tests OTPCredential</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/test-only-api.js"></script>
|
||||
<script src="support/otpcredential-helper.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
<script type="module">
|
||||
import {Status, expectOTPRequest} from './support/otpcredential-helper.js';
|
||||
|
||||
promise_test(async t => {
|
||||
await expect(receive).andReturn(async () => {
|
||||
return {status: Status.kSuccess, otp: "ABC"};
|
||||
});
|
||||
await expectOTPRequest().andReturn(
|
||||
() => ({status: Status.SUCCESS, otp: "ABC"}));
|
||||
|
||||
let cred = await navigator.credentials.get({otp: {transport: ["sms"]}});
|
||||
|
||||
|
@ -19,17 +16,15 @@ promise_test(async t => {
|
|||
}, 'Basic usage');
|
||||
|
||||
promise_test(async t => {
|
||||
await expect(receive).andReturn(async () => {
|
||||
return {status: Status.kSuccess, otp: "ABC"};
|
||||
});
|
||||
await expect(receive).andReturn(async () => {
|
||||
return {status: Status.kSuccess, otp: "ABC2"};
|
||||
});
|
||||
await expectOTPRequest().andReturn(
|
||||
() => ({status: Status.SUCCESS, otp: "ABC"}));
|
||||
await expectOTPRequest().andReturn(
|
||||
() => ({status: Status.SUCCESS, otp: "ABC2"}));
|
||||
|
||||
let sms1 = 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;
|
||||
|
||||
assert_equals(cred1.code, "ABC");
|
||||
|
@ -37,21 +32,18 @@ promise_test(async t => {
|
|||
}, 'Handle multiple requests in different order.');
|
||||
|
||||
promise_test(async t => {
|
||||
await expect(receive).andReturn(async () => {
|
||||
return {status: Status.kCancelled};
|
||||
});
|
||||
await expect(receive).andReturn(async () => {
|
||||
return {status: Status.kSuccess, otp: "success"};
|
||||
});
|
||||
await expectOTPRequest().andReturn(() => ({status: Status.CANCELLED}));
|
||||
await expectOTPRequest().andReturn(
|
||||
() => ({status: Status.SUCCESS, otp: "success"}));
|
||||
|
||||
let cancelled_sms = navigator.credentials.get({otp: {transport: ["sms"]}});
|
||||
let successful_sms = navigator.credentials.get({otp: {transport: ["sms"]}});
|
||||
let cancelledRequest = navigator.credentials.get({otp: {transport: ["sms"]}});
|
||||
let successfulCred =
|
||||
await navigator.credentials.get({otp: {transport: ["sms"]}});
|
||||
|
||||
let successful_cred = await successful_sms;
|
||||
assert_equals(successful_cred.code, "success");
|
||||
assert_equals(successfulCred.code, "success");
|
||||
|
||||
try {
|
||||
await cancelled_sms;
|
||||
await cancelledRequest;
|
||||
assert_unreached('Expected AbortError to be thrown.');
|
||||
} catch (error) {
|
||||
assert_equals(error.name, "AbortError");
|
||||
|
@ -59,9 +51,7 @@ promise_test(async t => {
|
|||
}, 'Handle multiple requests with success and error.');
|
||||
|
||||
promise_test(async t => {
|
||||
await expect(receive).andReturn(async () => {
|
||||
return {status: Status.kCancelled};
|
||||
});
|
||||
await expectOTPRequest().andReturn(() => ({status: Status.CANCELLED}));
|
||||
|
||||
await promise_rejects_dom(t, 'AbortError', navigator.credentials.get(
|
||||
{otp: {transport: ["sms"]}}));
|
||||
|
|
|
@ -1,52 +1,114 @@
|
|||
'use strict';
|
||||
|
||||
// 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 order to reduce the amount of test-only code shipped to users. To enable
|
||||
// these tests the browser must be run with these options:
|
||||
// // --enable-blink-features=MojoJS,MojoJSTest
|
||||
|
||||
const Status = {};
|
||||
import {isChromiumBased} from '/resources/test-only-api.m.js';
|
||||
|
||||
async function loadChromiumResources() {
|
||||
const resources = [
|
||||
'/gen/mojo/public/mojom/base/time.mojom-lite.js',
|
||||
'/gen/third_party/blink/public/mojom/sms/webotp_service.mojom-lite.js',
|
||||
];
|
||||
|
||||
await loadMojoResources(resources, true);
|
||||
await loadScript('/resources/chromium/mock-sms-receiver.js');
|
||||
|
||||
Status.kSuccess = blink.mojom.SmsStatus.kSuccess;
|
||||
Status.kTimeout = blink.mojom.SmsStatus.kTimeout;
|
||||
Status.kCancelled = blink.mojom.SmsStatus.kCancelled;
|
||||
/**
|
||||
* This enumeration is used by WebOTP WPTs to control mock backend behavior.
|
||||
* See MockWebOTPService below.
|
||||
*/
|
||||
export const Status = {
|
||||
SUCCESS: 0,
|
||||
UNHANDLED_REQUEST: 1,
|
||||
CANCELLED: 2,
|
||||
ABORTED: 3,
|
||||
};
|
||||
|
||||
async function create_sms_provider() {
|
||||
if (typeof SmsProvider === 'undefined') {
|
||||
if (isChromiumBased) {
|
||||
await loadChromiumResources();
|
||||
} else {
|
||||
throw new Error('Mojo testing interface is not available.');
|
||||
}
|
||||
}
|
||||
if (typeof SmsProvider === 'undefined') {
|
||||
throw new Error('Failed to set up SmsProvider.');
|
||||
}
|
||||
return new SmsProvider();
|
||||
/**
|
||||
* A interface which must be implemented by browsers to support WebOTP WPTs.
|
||||
*/
|
||||
export class MockWebOTPService {
|
||||
/**
|
||||
* 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
|
||||
* defined above, and -- if successful -- an `otp` field containing a
|
||||
* simulated OTP string.
|
||||
*
|
||||
* 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 {
|
||||
async andReturn(callback) {
|
||||
const mock = await create_sms_provider();
|
||||
mock.pushReturnValuesForTesting(call.name, callback);
|
||||
const mock = await asyncMock;
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<!doctype html>
|
||||
<script src="/resources/test-only-api.js"></script>
|
||||
<script src="otpcredential-helper.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
<script type="module">
|
||||
import {Status, expectOTPRequest} from './otpcredential-helper.js';
|
||||
|
||||
// Loading otpcredential-iframe.html in the test will make an OTPCredentials
|
||||
// call on load, and trigger a postMessage upon completion.
|
||||
|
@ -13,24 +11,16 @@
|
|||
// 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 () => {
|
||||
try {
|
||||
const credentials =
|
||||
await navigator.credentials.get({otp: {transport: ["sms"]}});
|
||||
window.parent.postMessage({result: "Pass", code: credentials.code}, '*');
|
||||
} catch (error) {
|
||||
window.parent.postMessage({result: "Fail", errorType: error.name}, '*');
|
||||
}
|
||||
try {
|
||||
await expectOTPRequest().andReturn(
|
||||
() => ({status: Status.SUCCESS, otp: "ABC123"}));
|
||||
const credentials =
|
||||
await navigator.credentials.get({otp: {transport: ["sms"]}});
|
||||
window.parent.postMessage({result: "Pass", code: credentials.code}, '*');
|
||||
} catch (error) {
|
||||
window.parent.postMessage({result: "Fail", errorType: error.name}, '*');
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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 <clipPath></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 |
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -85,6 +85,10 @@ test(function() {
|
|||
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');
|
||||
}, "Various tests");
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2 KiB |
After Width: | Height: | Size: 2 KiB |
After Width: | Height: | Size: 2 KiB |
After Width: | Height: | Size: 2 KiB |
|
@ -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);
|
||||
})
|
||||
}
|
21
tests/wpt/web-platform-tests/density-size-correction/third_party/piexif/LICENSE.txt
vendored
Normal 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.
|
2482
tests/wpt/web-platform-tests/density-size-correction/third_party/piexif/piexif.js
vendored
Normal 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>
|
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html>
|
||||
<iframe id="iframe" loading="lazy" src="subframe.html"></iframe>
|
|
@ -1,11 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="utf-8" />
|
||||
<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/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src='/resources/testdriver-vendor.js'></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
setup({
|
||||
|
@ -23,7 +23,7 @@ const applePay = Object.freeze({
|
|||
countryCode: "US",
|
||||
merchantCapabilities: ["supports3DS"],
|
||||
supportedNetworks: ["visa"],
|
||||
}
|
||||
},
|
||||
});
|
||||
const defaultMethods = Object.freeze([basicCard, applePay]);
|
||||
const defaultDetails = Object.freeze({
|
||||
|
@ -44,24 +44,22 @@ promise_test(async t => {
|
|||
|
||||
promise_test(async t => {
|
||||
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");
|
||||
}, "Calling abort() multiple times is always a new object.");
|
||||
|
||||
promise_test(async t => {
|
||||
const request = new PaymentRequest(defaultMethods, defaultDetails);
|
||||
const [abortPromise, acceptPromise] = await test_driver.bless(
|
||||
"show payment request",
|
||||
() => {
|
||||
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 test_driver.bless("show payment request");
|
||||
const acceptPromise = request.show();
|
||||
await request.abort();
|
||||
await promise_rejects_dom(t, "AbortError", acceptPromise);
|
||||
// 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());
|
||||
}, "The same request cannot be shown multiple times.");
|
||||
|
||||
|
@ -73,22 +71,21 @@ promise_test(async t => {
|
|||
await promise_rejects_dom(t, "InvalidStateError", request.abort());
|
||||
// The request's state is "created", so let's show it
|
||||
// which changes the state to "interactive.".
|
||||
const [abortPromise, acceptPromise] = await test_driver.bless(
|
||||
"show payment request",
|
||||
() => {
|
||||
const acceptPromise = request.show()
|
||||
// Let's set request the state to "closed" by calling .abort()
|
||||
const abortPromise = request.abort();
|
||||
return [abortPromise, acceptPromise];
|
||||
});
|
||||
|
||||
await abortPromise;
|
||||
await test_driver.bless("show payment request");
|
||||
const acceptPromise = request.show();
|
||||
// Let's set request the state to "closed" by calling .abort()
|
||||
await request.abort();
|
||||
// The request is now "closed", so...
|
||||
await promise_rejects_dom(t, "InvalidStateError", request.abort());
|
||||
await promise_rejects_dom(t, "AbortError", acceptPromise);
|
||||
}, "Aborting a request before it is shown doesn't prevent it from being shown later.");
|
||||
</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>.
|
||||
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>
|
||||
|
|
|
@ -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>
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="utf-8" />
|
||||
<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/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
|
@ -21,7 +21,7 @@ const defaultMethods = Object.freeze([
|
|||
countryCode: "US",
|
||||
merchantCapabilities: ["supports3DS"],
|
||||
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 acceptPromise = request.show();
|
||||
// Abort the request after 2 seconds if it has not rejected. This allows the
|
||||
|
@ -46,62 +46,64 @@ promise_test(async t => {
|
|||
request.abort();
|
||||
}, 2000);
|
||||
|
||||
await promise_rejects_dom(t, "SecurityError", acceptPromise);
|
||||
await promise_rejects_dom(t, "NotAllowedError", acceptPromise);
|
||||
}, `Calling show() without being triggered by user interaction throws`);
|
||||
|
||||
promise_test(async t => {
|
||||
promise_test(async (t) => {
|
||||
const request = new PaymentRequest(defaultMethods, defaultDetails);
|
||||
const [acceptPromise] = await test_driver.bless(
|
||||
"test: throws if the promise [[state]] is not 'created'",
|
||||
() => {
|
||||
const acceptPromise = request.show(); // Sets state to "interactive"
|
||||
return [acceptPromise];
|
||||
});
|
||||
await test_driver.bless(
|
||||
"test: throws if the promise [[state]] is not 'created'"
|
||||
);
|
||||
const acceptPromise = request.show(); // Sets state to "interactive"
|
||||
// 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 request.abort();
|
||||
await promise_rejects_dom(t, "AbortError", acceptPromise);
|
||||
}, "Throws if the promise [[state]] is not 'created'.");
|
||||
|
||||
promise_test(async t => {
|
||||
promise_test(async (t) => {
|
||||
const request1 = 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`,
|
||||
async () => {
|
||||
const acceptPromise1 = request1.show();
|
||||
const acceptPromise2 = request2.show();
|
||||
await promise_rejects_dom(t, "AbortError", acceptPromise2);
|
||||
return [acceptPromise1];
|
||||
});
|
||||
|
||||
await test_driver.bless("payment request");
|
||||
const acceptPromise1 = request1.show();
|
||||
|
||||
// User activation consumed, so...
|
||||
await promise_rejects_dom(t, "NotAllowedError", request2.show());
|
||||
|
||||
// Payment request already showing, so...
|
||||
await test_driver.bless("payment request");
|
||||
await promise_rejects_dom(t, "AbortError", request2.show());
|
||||
|
||||
await request1.abort();
|
||||
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.`);
|
||||
|
||||
promise_test(async t => {
|
||||
promise_test(async (t) => {
|
||||
const request = new PaymentRequest(
|
||||
[{ supportedMethods: "this-is-not-supported" }],
|
||||
defaultDetails
|
||||
);
|
||||
const [acceptPromise] = await test_driver.bless(
|
||||
`test: reject promise with "NotSupportedError"`,
|
||||
() => {
|
||||
const acceptPromise = request.show();
|
||||
return [acceptPromise];
|
||||
});
|
||||
await test_driver.bless(`test: reject promise with "NotSupportedError"`);
|
||||
const acceptPromise = request.show();
|
||||
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.`);
|
||||
|
||||
promise_test(async t => {
|
||||
promise_test(async (t) => {
|
||||
const request = new PaymentRequest(defaultMethods, defaultDetails);
|
||||
const [p1, p2, p3] = await test_driver.bless(
|
||||
`test: calling show() multiple times always returns a new promise`,
|
||||
() => {
|
||||
const p1 = request.show();
|
||||
const p2 = request.show();
|
||||
const p3 = request.show();
|
||||
return [p1, p2, p3];
|
||||
});
|
||||
await test_driver.bless("call show()");
|
||||
const p1 = request.show();
|
||||
await test_driver.bless("call show()");
|
||||
const p2 = request.show();
|
||||
await test_driver.bless("call show()");
|
||||
const p3 = request.show();
|
||||
const promises = new Set([p1, p2, p3]);
|
||||
assert_equals(promises.size, 3, "Must have three unique objects");
|
||||
|
||||
|
@ -111,9 +113,13 @@ promise_test(async t => {
|
|||
await request.abort();
|
||||
await promise_rejects_dom(t, "AbortError", p1);
|
||||
}, "Calling show() multiple times always returns a new promise.");
|
||||
|
||||
</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>.
|
||||
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>
|
||||
|
|
|
@ -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>
|
|
@ -1,15 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="utf-8" />
|
||||
<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/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script>
|
||||
// See function testBadUpdate() for test details!
|
||||
setup({
|
||||
allow_uncaught_exception: true,
|
||||
explicit_done: true,
|
||||
explicit_timeout: true,
|
||||
});
|
||||
|
||||
// == TEST DATA ===
|
||||
|
@ -30,7 +33,7 @@
|
|||
countryCode: "US",
|
||||
merchantCapabilities: ["supports3DS"],
|
||||
supportedNetworks: ["visa"],
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Methods
|
||||
|
@ -149,7 +152,7 @@
|
|||
Object.freeze(recursiveData);
|
||||
|
||||
const modifierWithRecursiveData = Object.freeze({
|
||||
supportedMethods: validMethodBasicCard,
|
||||
supportedMethods: "basic-card",
|
||||
total: validTotal,
|
||||
data: recursiveData,
|
||||
});
|
||||
|
@ -160,20 +163,19 @@
|
|||
The `badDetails` cause detailsPromise to reject with `expectedError`.
|
||||
*/
|
||||
function testBadUpdate(testAssertion, badDetails, expectedError) {
|
||||
promise_test(async t => {
|
||||
promise_test(async (t) => {
|
||||
const request = new PaymentRequest(
|
||||
validMethods,
|
||||
validDetails,
|
||||
validOptions
|
||||
);
|
||||
await test_driver.bless("Payment request");
|
||||
const detailsPromise = Promise.resolve(badDetails);
|
||||
const acceptPromise = request.show(detailsPromise);
|
||||
let test_func;
|
||||
if (typeof expectedError == "function") {
|
||||
test_func = promise_rejects_js;
|
||||
} else {
|
||||
test_func = promise_rejects_dom;
|
||||
}
|
||||
const test_func =
|
||||
typeof expectedError == "function"
|
||||
? promise_rejects_js
|
||||
: promise_rejects_dom;
|
||||
await test_func(
|
||||
t,
|
||||
expectedError,
|
||||
|
@ -182,113 +184,70 @@
|
|||
);
|
||||
}, 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 invalidDetails = { total: `this will cause a TypeError!` };
|
||||
testBadUpdate(this.textContent, invalidDetails, TypeError);
|
||||
">
|
||||
Total in the update is a string, so converting to IDL must abort the update with a TypeError.
|
||||
</button></li>
|
||||
const rejectedPromise = Promise.reject(new SyntaxError("test"));
|
||||
testBadUpdate(
|
||||
"Rejection of detailsPromise must abort the update with an 'AbortError' DOMException.",
|
||||
rejectedPromise,
|
||||
"AbortError"
|
||||
);
|
||||
|
||||
<li><button onclick="
|
||||
const invalidDetails = { total: recursiveData };
|
||||
testBadUpdate(this.textContent, invalidDetails, TypeError);
|
||||
">
|
||||
Total is recursive, so converting to IDL must abort the update with a TypeError.
|
||||
</button></li>
|
||||
testBadUpdate(
|
||||
"Total in the update is a string, so converting to IDL must abort the update with a TypeError.",
|
||||
{ total: `this will cause a TypeError!` },
|
||||
TypeError
|
||||
);
|
||||
|
||||
<li><button onclick="
|
||||
testBadUpdate(this.textContent, invalidDetailsNegativeTotal, TypeError);
|
||||
">
|
||||
Updating with a negative total results in a TypeError.
|
||||
</button></li>
|
||||
testBadUpdate(
|
||||
"Total is recursive, so converting to IDL must abort the update with a TypeError.",
|
||||
{ total: recursiveData },
|
||||
TypeError
|
||||
);
|
||||
|
||||
<li><button onclick="
|
||||
const badDetails = Object.assign({}, validDetails, {
|
||||
displayItems: invalidPaymentItems
|
||||
});
|
||||
testBadUpdate(this.textContent, badDetails, RangeError);
|
||||
">
|
||||
Updating with a displayItem with an invalid currency results in RangeError.
|
||||
</button></li>
|
||||
testBadUpdate(
|
||||
"Updating with a negative total results in a TypeError.",
|
||||
invalidDetailsNegativeTotal,
|
||||
TypeError
|
||||
);
|
||||
|
||||
<li><button onclick="
|
||||
const duplicateShippingOptions = [validShippingOption, validShippingOption];
|
||||
const badDetails = Object.assign({}, validDetails, {
|
||||
shippingOptions: duplicateShippingOptions,
|
||||
});
|
||||
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>
|
||||
testBadUpdate(
|
||||
"Updating with a displayItem with an invalid currency results in RangeError.",
|
||||
{ ...validDetails, displayItems: invalidPaymentItems },
|
||||
RangeError
|
||||
);
|
||||
|
||||
<li><button onclick="
|
||||
// validModifier is there as to avoid false positives
|
||||
const badModifiers = { modifiers: [modifierWithInvalidTotal, validModifier] };
|
||||
const badDetails = Object.assign({}, validDetails, badModifiers);
|
||||
testBadUpdate(this.textContent, badDetails, RangeError);
|
||||
">
|
||||
Must throw a RangeError when a modifier's total item has an invalid currency.
|
||||
</button></li>
|
||||
testBadUpdate(
|
||||
"Updating with duplicate shippingOptions (same IDs) results in a TypeError.",
|
||||
{
|
||||
...validDetails,
|
||||
shippingOptions: [validShippingOption, validShippingOption],
|
||||
},
|
||||
TypeError
|
||||
);
|
||||
|
||||
<li><button onclick="
|
||||
// validModifier is there as to avoid false positives
|
||||
const badModifiers = {
|
||||
testBadUpdate(
|
||||
"Updating with a shippingOption with an invalid currency value results in a RangError.",
|
||||
{ ...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],
|
||||
};
|
||||
const badDetails = Object.assign({}, validDetails, badModifiers);
|
||||
testBadUpdate(this.textContent, badDetails, RangeError);
|
||||
">
|
||||
Must throw a RangeError when a modifier display item has an invalid currency.
|
||||
</button></li>
|
||||
|
||||
<li><button onclick="
|
||||
// validModifier is there as to avoid false positives
|
||||
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>
|
||||
},
|
||||
RangeError
|
||||
);
|
||||
testBadUpdate(
|
||||
"Must throw as Modifier has a recursive dictionary.",
|
||||
{ ...validDetails, modifiers: [modifierWithRecursiveData, validModifier] },
|
||||
TypeError
|
||||
);
|
||||
</script>
|
|
@ -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;
|
||||
})();
|
|
@ -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;
|