mirror of
https://github.com/servo/servo.git
synced 2025-06-27 10:33:39 +01:00
Update web-platform-tests to revision 2b4f117a8fc636fc316b3864763db6b28e8a42bc
This commit is contained in:
parent
d7e7e43a80
commit
7ae94b8030
116 changed files with 3431 additions and 487 deletions
|
@ -4,7 +4,7 @@
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
|
|
||||||
[Opening a blob URL in a new window immediately before revoking it works.]
|
[Opening a blob URL in a new window immediately before revoking it works.]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[Fetching a blob URL immediately before revoking it works in an iframe.]
|
[Fetching a blob URL immediately before revoking it works in an iframe.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[hit-test-floats-003.html]
|
||||||
|
[Miss float below something else]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[hit-test-floats-004.html]
|
||||||
|
[Miss float below something else]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[hit-test-floats-005.html]
|
||||||
|
[Miss clipped float]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[one-element-animation.html]
|
||||||
|
expected: TIMEOUT
|
|
@ -0,0 +1,4 @@
|
||||||
|
[elementFromPoint-001.html]
|
||||||
|
[CSSOM View - 5 - extensions to the Document interface]
|
||||||
|
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
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
[offsetTopLeft-border-box.html]
|
||||||
|
[container: 1]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[container: 0]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -315,18 +315,21 @@
|
||||||
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
|
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: separate response Content-Type: text/html */*]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
|
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
|
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: combined response Content-Type: text/html;" text/plain]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: combined response Content-Type: text/html */*]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: separate response Content-Type: text/plain */*]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -53,3 +53,6 @@
|
||||||
[combined text/javascript ]
|
[combined text/javascript ]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[separate text/javascript x/x]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,6 @@
|
||||||
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
|
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[X-Content-Type-Options%3A%0D%0AX-Content-Type-Options%3A%20nosniff]
|
[X-Content-Type-Options%3A%20'NosniFF']
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[traverse_the_history_1.html]
|
||||||
|
[Multiple history traversals from the same task]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[sandbox-javascript-window-open.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[window.open in sandbox iframe]
|
||||||
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
[embedded-opener-remove-frame.html]
|
[embedded-opener-remove-frame.html]
|
||||||
expected: TIMEOUT
|
|
||||||
[opener of discarded nested browsing context]
|
[opener of discarded nested browsing context]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[opener of discarded auxiliary browsing context]
|
[opener of discarded auxiliary browsing context]
|
||||||
expected: TIMEOUT
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -171,3 +171,6 @@
|
||||||
[XHTML img usemap="#hash-id"]
|
[XHTML img usemap="#hash-id"]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[HTML (standards) IMG usemap="no-hash-name"]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[iframe_sandbox_popups_escaping-1.html]
|
[iframe_sandbox_popups_escaping-1.html]
|
||||||
expected: TIMEOUT
|
expected: CRASH
|
||||||
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[iframe_sandbox_popups_escaping-3.html]
|
[iframe_sandbox_popups_escaping-3.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[iframe_sandbox_popups_nonescaping-3.html]
|
[iframe_sandbox_popups_nonescaping-3.html]
|
||||||
expected: TIMEOUT
|
|
||||||
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
||||||
expected: NOTRUN
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[form-double-submit-3.html]
|
|
||||||
[<button> should have the same double-submit protection as <input type=submit>]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[activation-behavior.window.html]
|
|
||||||
[<a> that is not connected should be followed]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -20,3 +20,9 @@
|
||||||
[Test iframe from non-existent host]
|
[Test iframe from non-existent host]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Same-origin empty iframe with a 200 status gets reported]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Cross-origin empty iframe with a 200 status gets reported]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[realtimeanalyser-fft-scaling.html]
|
[realtimeanalyser-fft-scaling.html]
|
||||||
expected: TIMEOUT
|
|
||||||
[X 2048-point FFT peak position is not equal to 64. Got 0.]
|
[X 2048-point FFT peak position is not equal to 64. Got 0.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -380,3 +380,9 @@
|
||||||
[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\]\t9.9558435935349637e+18\t9.3139332532882690e-1\t9.9558435935349637e+18\t1.0689193622919801e+19\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.9558435935349637e+18 at index of 28696.\n\tMax RelError of 1.0689193622919801e+19 at index of 28696.\n]
|
[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\]\t9.9558435935349637e+18\t9.3139332532882690e-1\t9.9558435935349637e+18\t1.0689193622919801e+19\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.9558435935349637e+18 at index of 28696.\n\tMax RelError of 1.0689193622919801e+19 at index of 28696.\n]
|
||||||
expected: FAIL
|
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-1.6657697667767275e+26\t9.3139332532882690e-1\t1.6657697667767275e+26\t1.7884708011930731e+26\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 1.6657697667767275e+26 at index of 28696.\n\tMax RelError of 1.7884708011930731e+26 at index of 28696.\n]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[X SNR (-480.9982135660622 dB) is not greater than or equal to 65.737. Got -480.9982135660622.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[audiocontext-not-fully-active.html]
|
[audiocontext-not-fully-active.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[frame in navigated remote-site frame]
|
[frame in navigated remote-site frame]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[017.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[origin of the script that invoked the method, about:blank]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[017.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[origin of the script that invoked the method, about:blank]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[018.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[origin of the script that invoked the method, javascript:]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[sharedworker-in-worker.html]
|
[sharedworker-in-worker.html]
|
||||||
expected: ERROR
|
|
||||||
[Base URL in workers: new SharedWorker()]
|
[Base URL in workers: new SharedWorker()]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[Worker-constructor.html]
|
||||||
|
expected: ERROR
|
|
@ -7,7 +7,7 @@
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Opening a blob URL in a new window immediately before revoking it works.]
|
[Opening a blob URL in a new window immediately before revoking it works.]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
|
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,4 @@
|
||||||
|
[hit-test-floats-003.html]
|
||||||
|
[Miss float below something else]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[hit-test-floats-004.html]
|
||||||
|
[Miss float below something else]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[hit-test-floats-005.html]
|
||||||
|
[Miss clipped float]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[one-element-animation.html]
|
||||||
|
expected: TIMEOUT
|
|
@ -0,0 +1,2 @@
|
||||||
|
[image-orientation-iframe.html]
|
||||||
|
expected: TIMEOUT
|
|
@ -0,0 +1,4 @@
|
||||||
|
[elementFromPoint-001.html]
|
||||||
|
[CSSOM View - 5 - extensions to the Document interface]
|
||||||
|
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
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
[offsetTopLeft-border-box.html]
|
||||||
|
[container: 1]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[container: 0]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -315,18 +315,21 @@
|
||||||
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
|
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: separate response Content-Type: text/html */*]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
|
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
|
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: combined response Content-Type: text/html;" text/plain]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: combined response Content-Type: text/html */*]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: separate response Content-Type: text/plain */*]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -53,3 +53,6 @@
|
||||||
[combined text/javascript ]
|
[combined text/javascript ]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[separate text/javascript x/x]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,6 @@
|
||||||
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
|
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[X-Content-Type-Options%3A%0D%0AX-Content-Type-Options%3A%20nosniff]
|
[X-Content-Type-Options%3A%20'NosniFF']
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[traverse_the_history_1.html]
|
||||||
|
[Multiple history traversals from the same task]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[sandbox-javascript-window-open.html]
|
||||||
|
expected: TIMEOUT
|
||||||
|
[window.open in sandbox iframe]
|
||||||
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[embedded-opener-remove-frame.html]
|
[embedded-opener-remove-frame.html]
|
||||||
expected: TIMEOUT
|
|
||||||
[opener and "removed" embedded documents]
|
[opener and "removed" embedded documents]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -7,5 +6,5 @@
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[opener of discarded auxiliary browsing context]
|
[opener of discarded auxiliary browsing context]
|
||||||
expected: TIMEOUT
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -172,3 +172,6 @@
|
||||||
[XHTML img usemap="http://example.org/#garbage-before-hash-id"]
|
[XHTML img usemap="http://example.org/#garbage-before-hash-id"]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[HTML (standards) IMG usemap="no-hash-name"]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[iframe_sandbox_popups_escaping-1.html]
|
[iframe_sandbox_popups_escaping-1.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
expected: CRASH
|
||||||
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
[iframe_sandbox_popups_escaping-3.html]
|
[iframe_sandbox_popups_escaping-3.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
|
expected: TIMEOUT
|
||||||
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[iframe_sandbox_popups_nonescaping-3.html]
|
[iframe_sandbox_popups_nonescaping-3.html]
|
||||||
expected: TIMEOUT
|
|
||||||
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
[Check that popups from a sandboxed iframe do not escape the sandbox]
|
||||||
expected: NOTRUN
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[form-double-submit-3.html]
|
|
||||||
[<button> should have the same double-submit protection as <input type=submit>]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[activation-behavior.window.html]
|
|
||||||
[<a> that is not connected should be followed]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -20,3 +20,9 @@
|
||||||
[Test iframe from non-existent host]
|
[Test iframe from non-existent host]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Same-origin empty iframe with a 200 status gets reported]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Cross-origin empty iframe with a 200 status gets reported]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[realtimeanalyser-fft-scaling.html]
|
[realtimeanalyser-fft-scaling.html]
|
||||||
expected: TIMEOUT
|
|
||||||
[X 2048-point FFT peak position is not equal to 64. Got 0.]
|
[X 2048-point FFT peak position is not equal to 64. Got 0.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -608,3 +608,9 @@
|
||||||
[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\]\t9.9558435935349637e+18\t9.3139332532882690e-1\t9.9558435935349637e+18\t1.0689193622919801e+19\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.9558435935349637e+18 at index of 28696.\n\tMax RelError of 1.0689193622919801e+19 at index of 28696.\n]
|
[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\]\t9.9558435935349637e+18\t9.3139332532882690e-1\t9.9558435935349637e+18\t1.0689193622919801e+19\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.9558435935349637e+18 at index of 28696.\n\tMax RelError of 1.0689193622919801e+19 at index of 28696.\n]
|
||||||
expected: FAIL
|
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-1.6657697667767275e+26\t9.3139332532882690e-1\t1.6657697667767275e+26\t1.7884708011930731e+26\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 1.6657697667767275e+26 at index of 28696.\n\tMax RelError of 1.7884708011930731e+26 at index of 28696.\n]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[X SNR (-480.9982135660622 dB) is not greater than or equal to 65.737. Got -480.9982135660622.]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[audiocontext-not-fully-active.html]
|
[audiocontext-not-fully-active.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[frame in navigated remote-site frame]
|
[frame in navigated remote-site frame]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[017.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[origin of the script that invoked the method, about:blank]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[017.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[origin of the script that invoked the method, about:blank]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[018.html]
|
|
||||||
expected: TIMEOUT
|
|
||||||
[origin of the script that invoked the method, javascript:]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[sharedworker-in-worker.html]
|
[sharedworker-in-worker.html]
|
||||||
expected: ERROR
|
|
||||||
[Base URL in workers: new SharedWorker()]
|
[Base URL in workers: new SharedWorker()]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[Worker-constructor.html]
|
||||||
|
expected: ERROR
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas" width="100" height="100"></canvas>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var canvas = document.getElementById('canvas');
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
ctx.fillStyle = 'rgb(100, 100, 0)';
|
||||||
|
ctx.fillRect(0, 0, 100, 100);
|
||||||
|
</script>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#background-color">
|
||||||
|
<link rel="match" href="one-element-animation-ref.html">
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: green;
|
||||||
|
/* Use a long animation that start at 50% progress where the slope of the
|
||||||
|
selected timing function is zero. By setting up the animation in this way,
|
||||||
|
we accommodate lengthy delays in running the test without a potential drift
|
||||||
|
in the animated property value. This is important for avoiding flakes,
|
||||||
|
especially on debug builds. The screenshots are taken as soon as the
|
||||||
|
animation is ready, thus the long animation duration has no bearing on
|
||||||
|
the actual duration of the test. */
|
||||||
|
animation: bgcolor 1000000s cubic-bezier(0,1,1,0) -500000s;
|
||||||
|
}
|
||||||
|
@keyframes bgcolor {
|
||||||
|
0% { background-color: rgb(0, 200, 0); }
|
||||||
|
100% { background-color: rgb(200, 0, 0); }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="/common/reftest-wait.js"></script>
|
||||||
|
<body>
|
||||||
|
<div class="container"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getAnimations()[0].ready.then(() => {
|
||||||
|
takeScreenshot();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,8 +0,0 @@
|
||||||
<!doctype HTML>
|
|
||||||
<html>
|
|
||||||
<meta charset="utf8">
|
|
||||||
<title>CSS Content Visibility: auto in overflow hidden paints (reference)</title>
|
|
||||||
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
|
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
|
|
||||||
|
|
||||||
<div>content</div>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<!doctype HTML>
|
|
||||||
<meta charset="utf8">
|
|
||||||
<title>CSS Content Visibility: auto in overflow hidden paints</title>
|
|
||||||
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
|
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
|
|
||||||
<link rel="match" href="content-visibility-079-ref.html">
|
|
||||||
<meta name="assert" content="content-visibility auto element paints in an overflow hidden element that is not sized">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.auto { content-visibility: auto; }
|
|
||||||
.overflow { overflow: hidden; }
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class=overflow>
|
|
||||||
<div class=auto>content</div>
|
|
||||||
</div>
|
|
|
@ -124,6 +124,14 @@ Note that if the element to be clicked does not have a unique ID, the
|
||||||
document must not have any DOM mutations made between the function
|
document must not have any DOM mutations made between the function
|
||||||
being called and the promise settling.
|
being called and the promise settling.
|
||||||
|
|
||||||
|
## delete_all_cookies
|
||||||
|
|
||||||
|
Usage: `test_driver.delete_all_cookies(context=null)`
|
||||||
|
* _context_: an optional WindowProxy for the browsing context in which to
|
||||||
|
perform the call.
|
||||||
|
|
||||||
|
This function deletes all cookies for the current browsing context.
|
||||||
|
|
||||||
### send_keys
|
### send_keys
|
||||||
|
|
||||||
Usage: `test_driver.send_keys(element, keys)`
|
Usage: `test_driver.send_keys(element, keys)`
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script>
|
||||||
|
// Forward message from the openee toward the parent.
|
||||||
|
window.addEventListener("message", event => top.postMessage(event.data, "*"));
|
||||||
|
|
||||||
|
let check_sandboxed = `"
|
||||||
|
<script>
|
||||||
|
try {
|
||||||
|
document.domain = document.domain;
|
||||||
|
opener.postMessage('allow-document-domain', '*');
|
||||||
|
} catch (error) {
|
||||||
|
opener.postMessage('disallow-document-domain', '*');
|
||||||
|
}
|
||||||
|
</scr`+`ipt>
|
||||||
|
"`;
|
||||||
|
|
||||||
|
window.open('about:blank', "window_name");
|
||||||
|
window.open("javascript:" + check_sandboxed, "window_name");
|
||||||
|
</script>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>window.open in sandbox iframe</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/common/utils.js"></script>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
promise_test(async test => {
|
||||||
|
let message = new Promise(resolve => {
|
||||||
|
window.addEventListener("message", event => resolve(event.data));
|
||||||
|
});
|
||||||
|
let iframe = document.createElement("iframe");
|
||||||
|
iframe.sandbox = "allow-scripts allow-popups allow-same-origin";
|
||||||
|
iframe.src = "./resources/sandbox-javascript-window-open.html";
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
assert_equals(await message, "disallow-document-domain");
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,4 +1,4 @@
|
||||||
importScripts("/resources/testharness.js");
|
importScripts("/resources/testharness.js");
|
||||||
importScripts("module/evaluation-order-setup.mjs");
|
importScripts("module/evaluation-order-setup.mjs");
|
||||||
importScripts("module/evaluation-order-1-worker.mjs");
|
importScripts("evaluation-order-1-worker.js");
|
||||||
importScripts("module/evaluation-order-1.mjs");
|
importScripts("module/evaluation-order-1.mjs");
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
globalThis.expectedLog = [
|
||||||
|
"step-1-1", "step-1-2",
|
||||||
|
"global-error", "error",
|
||||||
|
"microtask",
|
||||||
|
];
|
||||||
|
|
||||||
|
globalThis.test_load.step_timeout(() => globalThis.testDone(), 0);
|
||||||
|
|
||||||
|
done();
|
|
@ -1,7 +1,7 @@
|
||||||
globalThis.expectedLog = [
|
globalThis.expectedLog = [
|
||||||
"step-1-1", "step-1-2",
|
"step-1-1", "step-1-2",
|
||||||
"global-error", "error",
|
|
||||||
"microtask",
|
"microtask",
|
||||||
|
"global-error", "error",
|
||||||
];
|
];
|
||||||
|
|
||||||
globalThis.test_load.step_timeout(() => globalThis.testDone(), 0);
|
globalThis.test_load.step_timeout(() => globalThis.testDone(), 0);
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
window.addEventListener("load", event => globalThis.testDone());
|
window.addEventListener("load", event => globalThis.testDone());
|
||||||
globalThis.expectedLog = [
|
globalThis.expectedLog = [
|
||||||
"step-1-1", "step-1-2",
|
"step-1-1", "step-1-2",
|
||||||
"global-error", "error",
|
|
||||||
"microtask",
|
"microtask",
|
||||||
|
"global-error", "error",
|
||||||
"script-load",
|
"script-load",
|
||||||
"global-load"
|
"global-load"
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
globalThis.expectedLog = [
|
globalThis.expectedLog = [
|
||||||
"step-2.2-1", "step-2.2-2",
|
"step-2.2-1", "step-2.2-2",
|
||||||
"global-error", "error",
|
|
||||||
"microtask-2.2",
|
"microtask-2.2",
|
||||||
|
"global-error", "error",
|
||||||
];
|
];
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
import "./evaluation-order-setup.mjs";
|
import "./evaluation-order-setup.mjs";
|
||||||
globalThis.expectedLog = [
|
globalThis.expectedLog = [
|
||||||
"step-2.2-1", "step-2.2-2",
|
"step-2.2-1", "step-2.2-2",
|
||||||
"global-error", "error",
|
|
||||||
"microtask-2.2",
|
"microtask-2.2",
|
||||||
|
"global-error", "error",
|
||||||
"script-load",
|
"script-load",
|
||||||
"global-load",
|
"global-load",
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>TestDriver delete_all_cookies method</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/testdriver.js"></script>
|
||||||
|
<script src="/resources/testdriver-vendor.js"></script>
|
||||||
|
<script>
|
||||||
|
promise_test(async t => {
|
||||||
|
document.cookie = "test1=1";
|
||||||
|
document.cookie = "test2=2; path=/";
|
||||||
|
document.cookie = "test3=3; path=/cookies/resources";
|
||||||
|
|
||||||
|
return test_driver.delete_all_cookies().then(() => {
|
||||||
|
assert_true(document.cookie === "");
|
||||||
|
});
|
||||||
|
}, "DOM-set cookies get deleted");
|
||||||
|
|
||||||
|
promise_test(async t => {
|
||||||
|
const cookie = "test1=1";
|
||||||
|
const encoded = encodeURIComponent(cookie);
|
||||||
|
await fetch(`/cookies/resources/cookie.py?set=${encoded}`)
|
||||||
|
|
||||||
|
const cookie2 = "test2=2; path=/";
|
||||||
|
const encoded2 = encodeURIComponent(cookie2);
|
||||||
|
await fetch(`/cookies/resources/cookie.py?set=${encoded2}`)
|
||||||
|
|
||||||
|
const cookie3 = "test3=3; path=/cookies/resources";
|
||||||
|
const encoded3 = encodeURIComponent(cookie3);
|
||||||
|
await fetch(`/cookies/resources/cookie.py?set=${encoded3}`)
|
||||||
|
|
||||||
|
const cookie4 = "test4=4; HttpOnly";
|
||||||
|
const encoded4 = encodeURIComponent(cookie4);
|
||||||
|
await fetch(`/cookies/resources/cookie.py?set=${encoded4}`)
|
||||||
|
|
||||||
|
return test_driver.delete_all_cookies().then(() => {
|
||||||
|
assert_true(document.cookie === "");
|
||||||
|
});
|
||||||
|
}, "HTTP-set cookies get deleted");
|
||||||
|
</script>
|
|
@ -724,6 +724,7 @@ MISSING DEPENDENCY: mediacapture-image/resources/imagecapture-helpers.js
|
||||||
MISSING DEPENDENCY: orientation-event/resources/orientation-event-helpers.js
|
MISSING DEPENDENCY: orientation-event/resources/orientation-event-helpers.js
|
||||||
MISSING DEPENDENCY: resources/test-only-api.js
|
MISSING DEPENDENCY: resources/test-only-api.js
|
||||||
MISSING DEPENDENCY: screen_enumeration/resources/screenenumeration-helpers.js
|
MISSING DEPENDENCY: screen_enumeration/resources/screenenumeration-helpers.js
|
||||||
|
MISSING DEPENDENCY: serial/resources/automation.js
|
||||||
MISSING DEPENDENCY: shape-detection/resources/shapedetection-helpers.js
|
MISSING DEPENDENCY: shape-detection/resources/shapedetection-helpers.js
|
||||||
MISSING DEPENDENCY: web-nfc/resources/nfc-helpers.js
|
MISSING DEPENDENCY: web-nfc/resources/nfc-helpers.js
|
||||||
MISSING DEPENDENCY: webusb/resources/usb-helpers.js
|
MISSING DEPENDENCY: webusb/resources/usb-helpers.js
|
||||||
|
|
|
@ -18,3 +18,8 @@ promise_test(async testCase => {
|
||||||
assert_equals(fileNames.indexOf('test_file'), -1);
|
assert_equals(fileNames.indexOf('test_file'), -1);
|
||||||
}, 'nativeIO.getAll does not return file deleted by nativeIO.delete');
|
}, 'nativeIO.getAll does not return file deleted by nativeIO.delete');
|
||||||
|
|
||||||
|
promise_test(async testCase => {
|
||||||
|
await nativeIO.delete('test_file');
|
||||||
|
// Delete a second time if the file existed before the first delete.
|
||||||
|
await nativeIO.delete('test_file');
|
||||||
|
}, 'nativeIO.delete does not fail when deleting a non-existing file');
|
||||||
|
|
|
@ -17,3 +17,9 @@ test(testCase => {
|
||||||
const fileNames = nativeIO.getAllSync();
|
const fileNames = nativeIO.getAllSync();
|
||||||
assert_equals(fileNames.indexOf('test_file'), -1);
|
assert_equals(fileNames.indexOf('test_file'), -1);
|
||||||
}, 'nativeIO.getAllSync does not return file deleted by nativeIO.deleteSync');
|
}, 'nativeIO.getAllSync does not return file deleted by nativeIO.deleteSync');
|
||||||
|
|
||||||
|
test(testCase => {
|
||||||
|
nativeIO.deleteSync('test_file');
|
||||||
|
// Delete a second time if the file existed before the first delete.
|
||||||
|
nativeIO.deleteSync('test_file');
|
||||||
|
}, 'nativeIO.deleteSync does not fail when deleting a non-existing file');
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
setup(async () => {
|
setup(async () => {
|
||||||
assert_implements(nativeIO.rename,
|
assert_implements(nativeIO.rename, 'nativeIO.rename is not implemented.');
|
||||||
"nativeIO.rename is not implemented.");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
promise_test(async testCase => {
|
promise_test(async testCase => {
|
||||||
|
@ -29,7 +28,8 @@ promise_test(async testCase => {
|
||||||
await file1.close();
|
await file1.close();
|
||||||
await file2.close();
|
await file2.close();
|
||||||
|
|
||||||
await promise_rejects_dom(testCase, "UnknownError",
|
await promise_rejects_dom(
|
||||||
|
testCase, 'NoModificationAllowedError',
|
||||||
nativeIO.rename('test_file_1', 'test_file_2'));
|
nativeIO.rename('test_file_1', 'test_file_2'));
|
||||||
|
|
||||||
const fileNamesAfterRename = await nativeIO.getAll();
|
const fileNamesAfterRename = await nativeIO.getAll();
|
||||||
|
@ -53,9 +53,11 @@ promise_test(async testCase => {
|
||||||
const readSharedArrayBuffer2 = new SharedArrayBuffer(writtenBytes2.length);
|
const readSharedArrayBuffer2 = new SharedArrayBuffer(writtenBytes2.length);
|
||||||
const readBytes2 = new Uint8Array(readSharedArrayBuffer2);
|
const readBytes2 = new Uint8Array(readSharedArrayBuffer2);
|
||||||
await file2_after.read(readBytes2, 0);
|
await file2_after.read(readBytes2, 0);
|
||||||
assert_array_equals(readBytes1, writtenBytes1,
|
assert_array_equals(
|
||||||
|
readBytes1, writtenBytes1,
|
||||||
'the bytes read should match the bytes written');
|
'the bytes read should match the bytes written');
|
||||||
assert_array_equals(readBytes2, writtenBytes2,
|
assert_array_equals(
|
||||||
|
readBytes2, writtenBytes2,
|
||||||
'the bytes read should match the bytes written');
|
'the bytes read should match the bytes written');
|
||||||
}, 'nativeIO.rename does not overwrite an existing file.');
|
}, 'nativeIO.rename does not overwrite an existing file.');
|
||||||
|
|
||||||
|
@ -65,7 +67,8 @@ promise_test(async testCase => {
|
||||||
await file.close();
|
await file.close();
|
||||||
await nativeIO.delete('test_file');
|
await nativeIO.delete('test_file');
|
||||||
});
|
});
|
||||||
await promise_rejects_dom(testCase, "UnknownError",
|
await promise_rejects_dom(
|
||||||
|
testCase, 'NoModificationAllowedError',
|
||||||
nativeIO.rename('test_file', 'renamed_test_file'));
|
nativeIO.rename('test_file', 'renamed_test_file'));
|
||||||
await file.close();
|
await file.close();
|
||||||
|
|
||||||
|
@ -86,10 +89,10 @@ promise_test(async testCase => {
|
||||||
const file = await nativeIO.open('test_file');
|
const file = await nativeIO.open('test_file');
|
||||||
await file.close();
|
await file.close();
|
||||||
for (let name of kBadNativeIoNames) {
|
for (let name of kBadNativeIoNames) {
|
||||||
await promise_rejects_js(testCase, TypeError,
|
await promise_rejects_js(
|
||||||
nativeIO.rename('test_file', name));
|
testCase, TypeError, nativeIO.rename('test_file', name));
|
||||||
await promise_rejects_js(testCase, TypeError,
|
await promise_rejects_js(
|
||||||
nativeIO.rename(name, 'test_file_2'));
|
testCase, TypeError, nativeIO.rename(name, 'test_file_2'));
|
||||||
}
|
}
|
||||||
}, 'nativeIO.rename does not allow renaming from or to invalid names.');
|
}, 'nativeIO.rename does not allow renaming from or to invalid names.');
|
||||||
|
|
||||||
|
@ -105,10 +108,12 @@ promise_test(async testCase => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// First rename fails, as source is still open.
|
// First rename fails, as source is still open.
|
||||||
await promise_rejects_dom(testCase, "UnknownError",
|
await promise_rejects_dom(
|
||||||
|
testCase, 'NoModificationAllowedError',
|
||||||
nativeIO.rename('opened_file', 'closed_file'));
|
nativeIO.rename('opened_file', 'closed_file'));
|
||||||
// First rename fails again, as source has not been unlocked.
|
// First rename fails again, as source has not been unlocked.
|
||||||
await promise_rejects_dom(testCase, "UnknownError",
|
await promise_rejects_dom(
|
||||||
|
testCase, 'NoModificationAllowedError',
|
||||||
nativeIO.rename('opened_file', 'closed_file'));
|
nativeIO.rename('opened_file', 'closed_file'));
|
||||||
}, 'Failed nativeIO.rename does not unlock the source.');
|
}, 'Failed nativeIO.rename does not unlock the source.');
|
||||||
|
|
||||||
|
@ -124,9 +129,22 @@ promise_test(async testCase => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// First rename fails, as destination is still open.
|
// First rename fails, as destination is still open.
|
||||||
await promise_rejects_dom(testCase, "UnknownError",
|
await promise_rejects_dom(
|
||||||
|
testCase, 'NoModificationAllowedError',
|
||||||
nativeIO.rename('closed_file', 'opened_file'));
|
nativeIO.rename('closed_file', 'opened_file'));
|
||||||
// First rename fails again, as destination has not been unlocked.
|
// First rename fails again, as destination has not been unlocked.
|
||||||
await promise_rejects_dom(testCase, "UnknownError",
|
await promise_rejects_dom(
|
||||||
|
testCase, 'NoModificationAllowedError',
|
||||||
nativeIO.rename('closed_file', 'opened_file'));
|
nativeIO.rename('closed_file', 'opened_file'));
|
||||||
}, 'Failed nativeIO.rename does not unlock the destination.');
|
}, 'Failed nativeIO.rename does not unlock the destination.');
|
||||||
|
|
||||||
|
promise_test(async testCase => {
|
||||||
|
// Make sure that the file does not exist.
|
||||||
|
await nativeIO.delete('does_not_exist');
|
||||||
|
testCase.add_cleanup(async () => {
|
||||||
|
await nativeIO.delete('new_does_not_exist');
|
||||||
|
});
|
||||||
|
await promise_rejects_dom(
|
||||||
|
testCase, 'NotFoundError',
|
||||||
|
nativeIO.rename('does_not_exist', 'new_does_not_exist'));
|
||||||
|
}, 'Renaming a non-existing file fails with a NotFoundError.');
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
setup(() => {
|
setup(() => {
|
||||||
// Without this assertion, one test passes even if renameSync is not defined
|
// Without this assertion, one test passes even if renameSync is not defined
|
||||||
assert_implements(nativeIO.renameSync,
|
assert_implements(
|
||||||
"nativeIO.renameSync is not implemented.");
|
nativeIO.renameSync, 'nativeIO.renameSync is not implemented.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test(testCase => {
|
test(testCase => {
|
||||||
|
@ -26,7 +26,8 @@ test(testCase => {
|
||||||
file1.close();
|
file1.close();
|
||||||
file2.close();
|
file2.close();
|
||||||
|
|
||||||
assert_throws_dom("UnknownError",
|
assert_throws_dom(
|
||||||
|
'NoModificationAllowedError',
|
||||||
() => nativeIO.renameSync('test_file_1', 'test_file_2'));
|
() => nativeIO.renameSync('test_file_1', 'test_file_2'));
|
||||||
|
|
||||||
const fileNamesAfterRename = nativeIO.getAllSync();
|
const fileNamesAfterRename = nativeIO.getAllSync();
|
||||||
|
@ -45,11 +46,13 @@ test(testCase => {
|
||||||
});
|
});
|
||||||
const readBytes1 = new Uint8Array(writtenBytes1.length);
|
const readBytes1 = new Uint8Array(writtenBytes1.length);
|
||||||
file1_after.read(readBytes1, 0);
|
file1_after.read(readBytes1, 0);
|
||||||
assert_array_equals(readBytes1, writtenBytes1,
|
assert_array_equals(
|
||||||
|
readBytes1, writtenBytes1,
|
||||||
'the bytes read should match the bytes written');
|
'the bytes read should match the bytes written');
|
||||||
const readBytes2 = new Uint8Array(writtenBytes2.length);
|
const readBytes2 = new Uint8Array(writtenBytes2.length);
|
||||||
file2_after.read(readBytes2, 0);
|
file2_after.read(readBytes2, 0);
|
||||||
assert_array_equals(readBytes2, writtenBytes2,
|
assert_array_equals(
|
||||||
|
readBytes2, writtenBytes2,
|
||||||
'the bytes read should match the bytes written');
|
'the bytes read should match the bytes written');
|
||||||
}, 'nativeIO.renameSync does not overwrite an existing file.');
|
}, 'nativeIO.renameSync does not overwrite an existing file.');
|
||||||
|
|
||||||
|
@ -59,8 +62,9 @@ test(testCase => {
|
||||||
file.close();
|
file.close();
|
||||||
nativeIO.deleteSync('test_file');
|
nativeIO.deleteSync('test_file');
|
||||||
});
|
});
|
||||||
assert_throws_dom("UnknownError", () =>
|
assert_throws_dom(
|
||||||
nativeIO.renameSync('test_file', 'renamed_test_file'));
|
'NoModificationAllowedError',
|
||||||
|
() => nativeIO.renameSync('test_file', 'renamed_test_file'));
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
const fileNamesAfterRename = nativeIO.getAllSync();
|
const fileNamesAfterRename = nativeIO.getAllSync();
|
||||||
|
@ -97,10 +101,12 @@ test(testCase => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// First rename fails, as source is still open.
|
// First rename fails, as source is still open.
|
||||||
assert_throws_dom("UnknownError",
|
assert_throws_dom(
|
||||||
|
'NoModificationAllowedError',
|
||||||
() => nativeIO.renameSync('opened_file', 'closed_file'));
|
() => nativeIO.renameSync('opened_file', 'closed_file'));
|
||||||
// First rename fails again, as source has not been unlocked.
|
// First rename fails again, as source has not been unlocked.
|
||||||
assert_throws_dom("UnknownError",
|
assert_throws_dom(
|
||||||
|
'NoModificationAllowedError',
|
||||||
() => nativeIO.renameSync('opened_file', 'closed_file'));
|
() => nativeIO.renameSync('opened_file', 'closed_file'));
|
||||||
}, 'Failed nativeIO.renameSync does not unlock the source.');
|
}, 'Failed nativeIO.renameSync does not unlock the source.');
|
||||||
|
|
||||||
|
@ -116,9 +122,22 @@ test(testCase => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// First rename fails, as destination is still open.
|
// First rename fails, as destination is still open.
|
||||||
assert_throws_dom("UnknownError",
|
assert_throws_dom(
|
||||||
|
'NoModificationAllowedError',
|
||||||
() => nativeIO.renameSync('closed_file', 'opened_file'));
|
() => nativeIO.renameSync('closed_file', 'opened_file'));
|
||||||
// First rename fails again, as destination has not been unlocked.
|
// First rename fails again, as destination has not been unlocked.
|
||||||
assert_throws_dom("UnknownError",
|
assert_throws_dom(
|
||||||
|
'NoModificationAllowedError',
|
||||||
() => nativeIO.renameSync('closed_file', 'opened_file'));
|
() => nativeIO.renameSync('closed_file', 'opened_file'));
|
||||||
}, 'Failed nativeIO.renameSync does not unlock the destination.');
|
}, 'Failed nativeIO.renameSync does not unlock the destination.');
|
||||||
|
|
||||||
|
test(testCase => {
|
||||||
|
// Make sure that the file does not exist.
|
||||||
|
nativeIO.deleteSync('does_not_exist');
|
||||||
|
testCase.add_cleanup(() => {
|
||||||
|
nativeIO.deleteSync('new_name');
|
||||||
|
});
|
||||||
|
assert_throws_dom(
|
||||||
|
'NotFoundError',
|
||||||
|
() => nativeIO.renameSync('does_not_exist', 'new_name'));
|
||||||
|
}, 'Renaming a non-existing file fails with a NotFoundError.');
|
||||||
|
|
|
@ -9,7 +9,10 @@
|
||||||
<script>
|
<script>
|
||||||
let reportedReferrer = () => {
|
let reportedReferrer = () => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
window.addEventListener("message", msg => resolve(msg.data.referrer));
|
window.addEventListener("message", function listener(msg) {
|
||||||
|
window.removeEventListener("message", listener, false);
|
||||||
|
resolve(msg.data.referrer);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,6 +32,7 @@
|
||||||
location.origin + "/custom");
|
location.origin + "/custom");
|
||||||
document.body.appendChild(iframe);
|
document.body.appendChild(iframe);
|
||||||
await iframe_load_1;
|
await iframe_load_1;
|
||||||
|
let referrer_1_result = await referrer_1;
|
||||||
|
|
||||||
// 2. Change the referrer policy of the main document.
|
// 2. Change the referrer policy of the main document.
|
||||||
document.getElementsByTagName('meta')[0].content = "unsafe-url";
|
document.getElementsByTagName('meta')[0].content = "unsafe-url";
|
||||||
|
@ -47,7 +51,7 @@
|
||||||
// Despite the main document has changed its referrer policy in (2), the
|
// Despite the main document has changed its referrer policy in (2), the
|
||||||
// reported referrer for the history navigation to about:srcdoc in (4) must
|
// reported referrer for the history navigation to about:srcdoc in (4) must
|
||||||
// match with the one originally reported in (1).
|
// match with the one originally reported in (1).
|
||||||
assert_equals(await referrer_1, undefined,
|
assert_equals(referrer_1_result, undefined,
|
||||||
"First navigation uses correct policy.");
|
"First navigation uses correct policy.");
|
||||||
assert_equals(await referrer_2, undefined,
|
assert_equals(await referrer_2, undefined,
|
||||||
"History navigation reuses original policy.");
|
"History navigation reuses original policy.");
|
||||||
|
@ -57,10 +61,13 @@
|
||||||
// If we initiate a new about:srcdoc navigation, the new referrer policy
|
// If we initiate a new about:srcdoc navigation, the new referrer policy
|
||||||
// should apply.
|
// should apply.
|
||||||
const new_iframe = document.createElement("iframe");
|
const new_iframe = document.createElement("iframe");
|
||||||
|
let new_iframe_load = iframeLoaded(new_iframe);
|
||||||
let new_iframe_referrer = reportedReferrer();
|
let new_iframe_referrer = reportedReferrer();
|
||||||
new_iframe.srcdoc = createScriptString(get_host_info().REMOTE_ORIGIN,
|
new_iframe.srcdoc = createScriptString(get_host_info().REMOTE_ORIGIN,
|
||||||
location.origin + "/custom");
|
location.origin + "/custom");
|
||||||
document.body.appendChild(new_iframe);
|
document.body.appendChild(new_iframe);
|
||||||
|
await new_iframe_load;
|
||||||
|
|
||||||
assert_equals(await new_iframe_referrer, self.origin + '/custom');
|
assert_equals(await new_iframe_referrer, self.origin + '/custom');
|
||||||
}, "New srcdoc iframe uses new policy.");
|
}, "New srcdoc iframe uses new policy.");
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -64,6 +64,16 @@ promise_test(t => {
|
||||||
return run_test(t, url.toString(), csp_directive);
|
return run_test(t, url.toString(), csp_directive);
|
||||||
}, "Cross-origin iframe that doesn't comply with CSP attribute gets reported");
|
}, "Cross-origin iframe that doesn't comply with CSP attribute gets reported");
|
||||||
|
|
||||||
|
promise_test(t => {
|
||||||
|
const url = new URL("/resource-timing/resources/200_empty.asis", location.href);
|
||||||
|
return run_test(t, url.toString(), csp_directive);
|
||||||
|
}, "Same-origin empty iframe with a 200 status gets reported");
|
||||||
|
|
||||||
|
promise_test(t => {
|
||||||
|
const url = new URL("/resource-timing/resources/200_empty.asis", REMOTE_ORIGIN);
|
||||||
|
return run_test(t, url.toString(), csp_directive);
|
||||||
|
}, "Cross-origin empty iframe with a 200 status gets reported");
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
HTTP/1.0 200 OK
|
||||||
|
Content-Length: 0
|
||||||
|
|
427
tests/wpt/web-platform-tests/resources/chromium/fake-serial.js
Normal file
427
tests/wpt/web-platform-tests/resources/chromium/fake-serial.js
Normal file
|
@ -0,0 +1,427 @@
|
||||||
|
// Implementation of an UnderlyingSource to create a ReadableStream from a Mojo
|
||||||
|
// data pipe consumer handle.
|
||||||
|
class DataPipeSource {
|
||||||
|
constructor(consumer) {
|
||||||
|
this.consumer_ = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
async pull(controller) {
|
||||||
|
let chunk = new ArrayBuffer(64);
|
||||||
|
let {result, numBytes} = this.consumer_.readData(chunk);
|
||||||
|
if (result == Mojo.RESULT_OK) {
|
||||||
|
controller.enqueue(new Uint8Array(chunk, 0, numBytes));
|
||||||
|
return;
|
||||||
|
} else if (result == Mojo.RESULT_FAILED_PRECONDITION) {
|
||||||
|
controller.close();
|
||||||
|
return;
|
||||||
|
} else if (result == Mojo.RESULT_SHOULD_WAIT) {
|
||||||
|
await this.readable();
|
||||||
|
return this.pull(controller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
if (this.watcher_)
|
||||||
|
this.watcher_.cancel();
|
||||||
|
this.consumer_.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
readable() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this.watcher_ =
|
||||||
|
this.consumer_.watch({ readable: true, peerClosed: true }, () => {
|
||||||
|
this.watcher_.cancel();
|
||||||
|
this.watcher_ = undefined;
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of an UnderlyingSink to create a WritableStream from a Mojo
|
||||||
|
// data pipe producer handle.
|
||||||
|
class DataPipeSink {
|
||||||
|
constructor(producer) {
|
||||||
|
this._producer = producer;
|
||||||
|
}
|
||||||
|
|
||||||
|
async write(chunk, controller) {
|
||||||
|
while (true) {
|
||||||
|
let {result, numBytes} = this._producer.writeData(chunk);
|
||||||
|
if (result == Mojo.RESULT_OK) {
|
||||||
|
if (numBytes == chunk.byteLength) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunk = chunk.slice(numBytes);
|
||||||
|
} else if (result == Mojo.RESULT_FAILED_PRECONDITION) {
|
||||||
|
throw new DOMException('The pipe is closed.', 'InvalidStateError');
|
||||||
|
} else if (result == Mojo.RESULT_SHOULD_WAIT) {
|
||||||
|
await this.writable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
assert_equals(undefined, this._watcher);
|
||||||
|
this._producer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(reason) {
|
||||||
|
if (this._watcher)
|
||||||
|
this._watcher.cancel();
|
||||||
|
this._producer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
writable() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this._watcher =
|
||||||
|
this._producer.watch({ writable: true, peerClosed: true }, () => {
|
||||||
|
this._watcher.cancel();
|
||||||
|
this._watcher = undefined;
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of blink.mojom.SerialPort.
|
||||||
|
class FakeSerialPort {
|
||||||
|
constructor() {
|
||||||
|
this.inputSignals_ = {
|
||||||
|
dataCarrierDetect: false,
|
||||||
|
clearToSend: false,
|
||||||
|
ringIndicator: false,
|
||||||
|
dataSetReady: false
|
||||||
|
};
|
||||||
|
this.inputSignalFailure_ = false;
|
||||||
|
this.outputSignals_ = {
|
||||||
|
dataTerminalReady: false,
|
||||||
|
requestToSend: false,
|
||||||
|
break: false
|
||||||
|
};
|
||||||
|
this.outputSignalFailure_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
open(options, client) {
|
||||||
|
if (this.binding_ !== undefined) {
|
||||||
|
// Port already open.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let portPtr = new device.mojom.SerialPortPtr();
|
||||||
|
this.binding_ = new mojo.Binding(
|
||||||
|
device.mojom.SerialPort, this, mojo.makeRequest(portPtr));
|
||||||
|
this.binding_.setConnectionErrorHandler(() => {
|
||||||
|
this.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.options_ = options;
|
||||||
|
this.client_ = client;
|
||||||
|
// OS typically sets DTR on open.
|
||||||
|
this.outputSignals_.dataTerminalReady = true;
|
||||||
|
|
||||||
|
return portPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(data) {
|
||||||
|
return this.writer_.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
read() {
|
||||||
|
return this.reader_.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reads from the port until at least |targetLength| is read or the stream is
|
||||||
|
// closed. The data is returned as a combined Uint8Array.
|
||||||
|
readWithLength(targetLength) {
|
||||||
|
return readWithLength(this.reader_, targetLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateReadError(error) {
|
||||||
|
this.writer_.close();
|
||||||
|
this.writer_.releaseLock();
|
||||||
|
this.writer_ = undefined;
|
||||||
|
this.writable_ = undefined;
|
||||||
|
this.client_.onReadError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateParityError() {
|
||||||
|
this.simulateReadError(device.mojom.SerialReceiveError.PARITY_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateDisconnectOnRead() {
|
||||||
|
this.simulateReadError(device.mojom.SerialReceiveError.DISCONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateWriteError(error) {
|
||||||
|
this.reader_.cancel();
|
||||||
|
this.reader_ = undefined;
|
||||||
|
this.readable_ = undefined;
|
||||||
|
this.client_.onSendError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateSystemErrorOnWrite() {
|
||||||
|
this.simulateWriteError(device.mojom.SerialSendError.SYSTEM_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateDisconnectOnWrite() {
|
||||||
|
this.simulateWriteError(device.mojom.SerialSendError.DISCONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateInputSignals(signals) {
|
||||||
|
this.inputSignals_ = signals;
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateInputSignalFailure(fail) {
|
||||||
|
this.inputSignalFailure_ = fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
get outputSignals() {
|
||||||
|
return this.outputSignals_;
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateOutputSignalFailure(fail) {
|
||||||
|
this.outputSignalFailure_ = fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
writable() {
|
||||||
|
if (this.writable_)
|
||||||
|
return Promise.resolve();
|
||||||
|
|
||||||
|
if (!this.writablePromise_) {
|
||||||
|
this.writablePromise_ = new Promise((resolve) => {
|
||||||
|
this.writableResolver_ = resolve;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.writablePromise_;
|
||||||
|
}
|
||||||
|
|
||||||
|
readable() {
|
||||||
|
if (this.readable_)
|
||||||
|
return Promise.resolve();
|
||||||
|
|
||||||
|
if (!this.readablePromise_) {
|
||||||
|
this.readablePromise_ = new Promise((resolve) => {
|
||||||
|
this.readableResolver_ = resolve;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.readablePromise_;
|
||||||
|
}
|
||||||
|
|
||||||
|
async startWriting(in_stream) {
|
||||||
|
this.readable_ = new ReadableStream(new DataPipeSource(in_stream));
|
||||||
|
this.reader_ = this.readable_.getReader();
|
||||||
|
if (this.readableResolver_) {
|
||||||
|
this.readableResolver_();
|
||||||
|
this.readableResolver_ = undefined;
|
||||||
|
this.readablePromise_ = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async startReading(out_stream) {
|
||||||
|
this.writable_ = new WritableStream(new DataPipeSink(out_stream));
|
||||||
|
this.writer_ = this.writable_.getWriter();
|
||||||
|
if (this.writableResolver_) {
|
||||||
|
this.writableResolver_();
|
||||||
|
this.writableResolver_ = undefined;
|
||||||
|
this.writablePromise_ = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async flush(mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case device.mojom.SerialPortFlushMode.kReceive:
|
||||||
|
this.writer_.abort();
|
||||||
|
this.writer_.releaseLock();
|
||||||
|
this.writer_ = undefined;
|
||||||
|
this.writable_ = undefined;
|
||||||
|
break;
|
||||||
|
case device.mojom.SerialPortFlushMode.kTransmit:
|
||||||
|
this.reader_.cancel();
|
||||||
|
this.reader_ = undefined;
|
||||||
|
this.readable_ = undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async drain() {
|
||||||
|
await this.reader_.closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getControlSignals() {
|
||||||
|
if (this.inputSignalFailure_) {
|
||||||
|
return {signals: null};
|
||||||
|
}
|
||||||
|
|
||||||
|
const signals = {
|
||||||
|
dcd: this.inputSignals_.dataCarrierDetect,
|
||||||
|
cts: this.inputSignals_.clearToSend,
|
||||||
|
ri: this.inputSignals_.ringIndicator,
|
||||||
|
dsr: this.inputSignals_.dataSetReady
|
||||||
|
};
|
||||||
|
return {signals};
|
||||||
|
}
|
||||||
|
|
||||||
|
async setControlSignals(signals) {
|
||||||
|
if (this.outputSignalFailure_) {
|
||||||
|
return {success: false};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signals.hasDtr) {
|
||||||
|
this.outputSignals_.dataTerminalReady = signals.dtr;
|
||||||
|
}
|
||||||
|
if (signals.hasRts) {
|
||||||
|
this.outputSignals_.requestToSend = signals.rts;
|
||||||
|
}
|
||||||
|
if (signals.hasBrk) {
|
||||||
|
this.outputSignals_.break = signals.brk;
|
||||||
|
}
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
async configurePort(options) {
|
||||||
|
this.options_ = options;
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPortInfo() {
|
||||||
|
return {
|
||||||
|
bitrate: this.options_.bitrate,
|
||||||
|
data_bits: this.options_.data_bits,
|
||||||
|
parity_bit: this.options_.parity_bit,
|
||||||
|
stop_bits: this.options_.stop_bits,
|
||||||
|
cts_flow_control: this.options_.has_cts_flow_control ?
|
||||||
|
this.options_.cts_flow_control : false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async close() {
|
||||||
|
// OS typically clears DTR on close.
|
||||||
|
this.outputSignals_.dataTerminalReady = false;
|
||||||
|
if (this.writer_) {
|
||||||
|
this.writer_.close();
|
||||||
|
this.writer_.releaseLock();
|
||||||
|
this.writer_ = undefined;
|
||||||
|
}
|
||||||
|
this.writable_ = undefined;
|
||||||
|
|
||||||
|
if (this.binding_) {
|
||||||
|
this.binding_.close();
|
||||||
|
this.binding_ = undefined;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of blink.mojom.SerialService.
|
||||||
|
class FakeSerialService {
|
||||||
|
constructor() {
|
||||||
|
this.interceptor_ =
|
||||||
|
new MojoInterfaceInterceptor(blink.mojom.SerialService.name);
|
||||||
|
this.interceptor_.oninterfacerequest = e => this.bind(e.handle);
|
||||||
|
this.bindingSet_ = new mojo.BindingSet(blink.mojom.SerialService);
|
||||||
|
this.clients_ = [];
|
||||||
|
this.nextToken_ = 0;
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.interceptor_.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
this.interceptor_.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.ports_ = new Map();
|
||||||
|
this.selectedPort_ = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
addPort(info) {
|
||||||
|
let portInfo = new blink.mojom.SerialPortInfo();
|
||||||
|
if (info?.usbVendorId !== undefined) {
|
||||||
|
portInfo.hasUsbVendorId = true;
|
||||||
|
portInfo.usbVendorId = info.usbVendorId;
|
||||||
|
}
|
||||||
|
if (info?.usbProductId !== undefined) {
|
||||||
|
portInfo.hasUsbProductId = true;
|
||||||
|
portInfo.usbProductId = info.usbProductId;
|
||||||
|
}
|
||||||
|
|
||||||
|
let token = ++this.nextToken_;
|
||||||
|
portInfo.token = new mojoBase.mojom.UnguessableToken();
|
||||||
|
portInfo.token.high = 0;
|
||||||
|
portInfo.token.low = token;
|
||||||
|
|
||||||
|
let record = {
|
||||||
|
portInfo: portInfo,
|
||||||
|
fakePort: new FakeSerialPort(),
|
||||||
|
};
|
||||||
|
this.ports_.set(token, record);
|
||||||
|
|
||||||
|
for (let client of this.clients_) {
|
||||||
|
client.onPortAdded(portInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
removePort(token) {
|
||||||
|
let record = this.ports_.get(token);
|
||||||
|
if (record === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ports_.delete(token);
|
||||||
|
|
||||||
|
for (let client of this.clients_) {
|
||||||
|
client.onPortRemoved(record.portInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedPort(token) {
|
||||||
|
this.selectedPort_ = this.ports_.get(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
getFakePort(token) {
|
||||||
|
let record = this.ports_.get(token);
|
||||||
|
if (record === undefined)
|
||||||
|
return undefined;
|
||||||
|
return record.fakePort;
|
||||||
|
}
|
||||||
|
|
||||||
|
bind(handle) {
|
||||||
|
this.bindingSet_.addBinding(this, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setClient(client_remote) {
|
||||||
|
this.clients_.push(client_remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getPorts() {
|
||||||
|
return {
|
||||||
|
ports: Array.from(this.ports_, ([token, record]) => record.portInfo)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async requestPort(filters) {
|
||||||
|
if (this.selectedPort_)
|
||||||
|
return { port: this.selectedPort_.portInfo };
|
||||||
|
else
|
||||||
|
return { port: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
async openPort(token, options, client) {
|
||||||
|
let record = this.ports_.get(token.low);
|
||||||
|
if (record !== undefined) {
|
||||||
|
return {port: record.fakePort.open(options, client)};
|
||||||
|
} else {
|
||||||
|
return {port: null};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeSerialService = new FakeSerialService();
|
|
@ -146,6 +146,24 @@
|
||||||
y: centerPoint[1]});
|
y: centerPoint[1]});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all cookies.
|
||||||
|
*
|
||||||
|
* This matches the behaviour of the {@link
|
||||||
|
* https://w3c.github.io/webdriver/#delete-all-cookies|WebDriver
|
||||||
|
* Delete All Cookies command}.
|
||||||
|
*
|
||||||
|
* @param {WindowProxy} context - Browsing context in which
|
||||||
|
* to run the call, or null for the current
|
||||||
|
* browsing context.
|
||||||
|
*
|
||||||
|
* @returns {Promise} fulfilled after cookies are deleted, or rejected in
|
||||||
|
* the cases the WebDriver command errors
|
||||||
|
*/
|
||||||
|
delete_all_cookies: function(context=null) {
|
||||||
|
return window.test_driver_internal.delete_all_cookies(context);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send keys to an element
|
* Send keys to an element
|
||||||
*
|
*
|
||||||
|
@ -458,6 +476,10 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
delete_all_cookies: function(context=null) {
|
||||||
|
return Promise.reject(new Error("unimplemented"));
|
||||||
|
},
|
||||||
|
|
||||||
send_keys: function(element, keys) {
|
send_keys: function(element, keys) {
|
||||||
if (this.in_automation) {
|
if (this.in_automation) {
|
||||||
return Promise.reject(new Error('Not implemented'));
|
return Promise.reject(new Error('Not implemented'));
|
||||||
|
|
75
tests/wpt/web-platform-tests/serial/resources/automation.js
Normal file
75
tests/wpt/web-platform-tests/serial/resources/automation.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// These tests rely on the User Agent providing an implementation of the
|
||||||
|
// FakeSerialService interface which replaces the platform-specific
|
||||||
|
// implementation of the Web Serial API with one that can be automated from
|
||||||
|
// Javascript for testing purposes.
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
async function loadChromiumResources() {
|
||||||
|
const chromiumResources = [
|
||||||
|
'/gen/mojo/public/mojom/base/unguessable_token.mojom.js',
|
||||||
|
'/gen/services/device/public/mojom/serial.mojom.js',
|
||||||
|
'/gen/third_party/blink/public/mojom/serial/serial.mojom.js',
|
||||||
|
];
|
||||||
|
await loadMojoResources(chromiumResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a SerialPort instance and associated FakeSerialPort instance.
|
||||||
|
async function getFakeSerialPort(fake) {
|
||||||
|
let token = fake.addPort();
|
||||||
|
let fakePort = fake.getFakePort(token);
|
||||||
|
|
||||||
|
let ports = await navigator.serial.getPorts();
|
||||||
|
assert_equals(ports.length, 1);
|
||||||
|
|
||||||
|
let port = ports[0];
|
||||||
|
assert_true(port instanceof SerialPort);
|
||||||
|
|
||||||
|
return { port, fakePort };
|
||||||
|
}
|
||||||
|
|
||||||
|
let fakeSerialService = undefined;
|
||||||
|
|
||||||
|
function serial_test(func, name, properties) {
|
||||||
|
promise_test(async (test) => {
|
||||||
|
assert_implements(navigator.serial, 'missing navigator.serial');
|
||||||
|
if (fakeSerialService === undefined) {
|
||||||
|
// Try loading a polyfill for the fake serial service.
|
||||||
|
if (isChromiumBased) {
|
||||||
|
await loadChromiumResources();
|
||||||
|
await loadScript('/resources/chromium/fake-serial.js');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_implements(fakeSerialService, 'missing fakeSerialService after initialization');
|
||||||
|
|
||||||
|
fakeSerialService.start();
|
||||||
|
try {
|
||||||
|
await func(test, fakeSerialService);
|
||||||
|
} finally {
|
||||||
|
fakeSerialService.stop();
|
||||||
|
fakeSerialService.reset();
|
||||||
|
}
|
||||||
|
}, name, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
function trustedClick() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
let button = document.createElement('button');
|
||||||
|
button.textContent = 'click to continue test';
|
||||||
|
button.style.display = 'block';
|
||||||
|
button.style.fontSize = '20px';
|
||||||
|
button.style.padding = '10px';
|
||||||
|
button.onclick = () => {
|
||||||
|
document.body.removeChild(button);
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
document.body.appendChild(button);
|
||||||
|
test_driver.click(button);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await promise_rejects_dom(t, 'InvalidStateError', port.close());
|
||||||
|
}, 'A SerialPort cannot be closed if it was never opened.');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await port.open({baudRate: 9600});
|
||||||
|
await port.close();
|
||||||
|
await promise_rejects_dom(t, 'InvalidStateError', port.close());
|
||||||
|
}, 'A SerialPort cannot be closed if it is already closed.');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await port.open({baudRate: 9600});
|
||||||
|
const closePromise = port.close();
|
||||||
|
await promise_rejects_dom(t, 'InvalidStateError', port.close());
|
||||||
|
await closePromise;
|
||||||
|
}, 'A SerialPort cannot be closed if it is being closed.');
|
|
@ -0,0 +1,197 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
const targets = [navigator.serial, port];
|
||||||
|
const expectedTargets = [navigator.serial];
|
||||||
|
|
||||||
|
const actualTargets = [];
|
||||||
|
function eventHandler(evt) {
|
||||||
|
actualTargets.push(evt.currentTarget);
|
||||||
|
|
||||||
|
if (evt.currentTarget == navigator.serial) {
|
||||||
|
evt.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.forEach((target) => {
|
||||||
|
target.addEventListener('foo', eventHandler, {capture: true});
|
||||||
|
// stopPropagation() during capturing prevents bubbling.
|
||||||
|
target.addEventListener('foo', eventHandler);
|
||||||
|
|
||||||
|
t.add_cleanup(() => {
|
||||||
|
target.removeEventListener('foo', eventHandler, {capture: true});
|
||||||
|
target.removeEventListener('foo', eventHandler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
port.dispatchEvent(new CustomEvent('foo', {bubbles: true}));
|
||||||
|
|
||||||
|
assert_array_equals(actualTargets, expectedTargets, 'actualTargets');
|
||||||
|
}, 'stopPropagation() during capturing');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
const targets = [navigator.serial, port];
|
||||||
|
const expectedTargets = [navigator.serial];
|
||||||
|
|
||||||
|
const actualTargets = [];
|
||||||
|
function eventHandler(evt) {
|
||||||
|
actualTargets.push(evt.currentTarget);
|
||||||
|
|
||||||
|
if (evt.currentTarget == navigator.serial) {
|
||||||
|
evt.cancelBubble = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.forEach((target) => {
|
||||||
|
target.addEventListener('foo', eventHandler, {capture: true});
|
||||||
|
// Setting cancelBubble during capturing prevents bubbling.
|
||||||
|
target.addEventListener('foo', eventHandler);
|
||||||
|
|
||||||
|
t.add_cleanup(() => {
|
||||||
|
target.removeEventListener('foo', eventHandler, {capture: true});
|
||||||
|
target.removeEventListener('foo', eventHandler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
port.dispatchEvent(new CustomEvent('foo', {bubbles: true}));
|
||||||
|
|
||||||
|
assert_array_equals(actualTargets, expectedTargets, 'actualTargets');
|
||||||
|
}, 'Set cancelBubble during capturing');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
const targets = [navigator.serial, port];
|
||||||
|
const expectedTargets = [port];
|
||||||
|
|
||||||
|
const actualTargets = [];
|
||||||
|
function eventHandler(evt) {
|
||||||
|
actualTargets.push(evt.currentTarget);
|
||||||
|
|
||||||
|
if (evt.currentTarget == port) {
|
||||||
|
evt.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.forEach((target) => {
|
||||||
|
target.addEventListener('foo', eventHandler);
|
||||||
|
|
||||||
|
t.add_cleanup(() => {
|
||||||
|
target.removeEventListener('foo', eventHandler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
port.dispatchEvent(new CustomEvent('foo', {bubbles: true}));
|
||||||
|
|
||||||
|
assert_array_equals(actualTargets, expectedTargets, 'actualTargets');
|
||||||
|
}, 'stopPropagation() during bubbling');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
const targets = [navigator.serial, port];
|
||||||
|
const expectedTargets = [port];
|
||||||
|
|
||||||
|
const actualTargets = [];
|
||||||
|
function eventHandler(evt) {
|
||||||
|
actualTargets.push(evt.currentTarget);
|
||||||
|
|
||||||
|
if (evt.currentTarget == port) {
|
||||||
|
evt.cancelBubble = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.forEach((target) => {
|
||||||
|
target.addEventListener('foo', eventHandler);
|
||||||
|
|
||||||
|
t.add_cleanup(() => {
|
||||||
|
target.removeEventListener('foo', eventHandler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
port.dispatchEvent(new CustomEvent('foo', {bubbles: true}));
|
||||||
|
|
||||||
|
assert_array_equals(actualTargets, expectedTargets, 'actualTargets');
|
||||||
|
}, 'Set cancelBubble during bubbling');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
const targets = [navigator.serial, port];
|
||||||
|
const expectedTargets = [
|
||||||
|
navigator.serial,
|
||||||
|
port,
|
||||||
|
navigator.serial,
|
||||||
|
port,
|
||||||
|
];
|
||||||
|
const expectedTypes = [
|
||||||
|
'foo',
|
||||||
|
'bar',
|
||||||
|
'bar',
|
||||||
|
'foo',
|
||||||
|
];
|
||||||
|
|
||||||
|
const actualTargets = [];
|
||||||
|
const actualTypes = [];
|
||||||
|
function eventHandler(evt) {
|
||||||
|
actualTargets.push(evt.currentTarget);
|
||||||
|
actualTypes.push(evt.type);
|
||||||
|
|
||||||
|
if (evt.currentTarget == navigator.serial && evt.type == 'foo') {
|
||||||
|
port.dispatchEvent(new CustomEvent('bar', {bubbles: true}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.forEach((target) => {
|
||||||
|
target.addEventListener('foo', eventHandler, {capture: true});
|
||||||
|
target.addEventListener('bar', eventHandler);
|
||||||
|
|
||||||
|
t.add_cleanup(() => {
|
||||||
|
target.removeEventListener('foo', eventHandler, {capture: true});
|
||||||
|
target.removeEventListener('bar', eventHandler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
port.dispatchEvent(new CustomEvent('foo', {bubbles: true}));
|
||||||
|
|
||||||
|
assert_array_equals(actualTargets, expectedTargets, 'actualTargets');
|
||||||
|
assert_array_equals(actualTypes, expectedTypes, 'actualTypes');
|
||||||
|
}, 'An event dispatched in an event handler is propagated before continuing');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
const targets = [navigator.serial, port];
|
||||||
|
const expected = [
|
||||||
|
'capturing Serial',
|
||||||
|
'capturing SerialPort',
|
||||||
|
'bubbling SerialPort',
|
||||||
|
'bubbling Serial',
|
||||||
|
];
|
||||||
|
|
||||||
|
const actual = [];
|
||||||
|
targets.forEach((target) => {
|
||||||
|
const bubblingEventHandler = () => {
|
||||||
|
actual.push(`bubbling ${target.constructor.name}`);
|
||||||
|
};
|
||||||
|
target.addEventListener('foo', bubblingEventHandler);
|
||||||
|
const capturingEventHandler = () => {
|
||||||
|
actual.push(`capturing ${target.constructor.name}`);
|
||||||
|
};
|
||||||
|
target.addEventListener('foo', capturingEventHandler, {capture: true});
|
||||||
|
|
||||||
|
t.add_cleanup(() => {
|
||||||
|
target.removeEventListener('foo', bubblingEventHandler, {capture: true});
|
||||||
|
target.removeEventListener('foo', capturingEventHandler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
port.dispatchEvent(new CustomEvent('foo', {bubbles: true}));
|
||||||
|
assert_array_equals(actual, expected);
|
||||||
|
}, 'Capturing and bubbling events delivered to listeners in the expected order');
|
|
@ -0,0 +1,24 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
// Wait for getPorts() to resolve in order to ensure that the Mojo client
|
||||||
|
// interface has been configured.
|
||||||
|
let ports = await navigator.serial.getPorts();
|
||||||
|
assert_equals(ports.length, 0);
|
||||||
|
|
||||||
|
[{},
|
||||||
|
{usbVendorId: 1},
|
||||||
|
{usbProductId: 2},
|
||||||
|
{usbVendorId: 1, usbProductId: 2},
|
||||||
|
].forEach((expectedInfo) => {
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
let watcher = new EventWatcher(t, navigator.serial, ['connect']);
|
||||||
|
fake.addPort(expectedInfo);
|
||||||
|
let evt = await watcher.wait_for(['connect']);
|
||||||
|
let info = evt.target.getInfo();
|
||||||
|
assert_object_equals(expectedInfo, info);
|
||||||
|
}, `getInfo() returns ${JSON.stringify(expectedInfo)}`);
|
||||||
|
});
|
||||||
|
}, 'getInfo() meta test');
|
|
@ -0,0 +1,63 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
await promise_rejects_dom(t, 'InvalidStateError', port.getSignals());
|
||||||
|
}, 'getSignals() rejects if the port is not open');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
await port.open({baudRate: 9600});
|
||||||
|
|
||||||
|
let expectedSignals = {
|
||||||
|
dataCarrierDetect: false,
|
||||||
|
clearToSend: false,
|
||||||
|
ringIndicator: false,
|
||||||
|
dataSetReady: false
|
||||||
|
};
|
||||||
|
fakePort.simulateInputSignals(expectedSignals);
|
||||||
|
let signals = await port.getSignals();
|
||||||
|
assert_object_equals(signals, expectedSignals);
|
||||||
|
|
||||||
|
expectedSignals.dataCarrierDetect = true;
|
||||||
|
fakePort.simulateInputSignals(expectedSignals);
|
||||||
|
signals = await port.getSignals();
|
||||||
|
assert_object_equals(signals, expectedSignals, 'DCD set');
|
||||||
|
|
||||||
|
expectedSignals.clearToSend = true;
|
||||||
|
fakePort.simulateInputSignals(expectedSignals);
|
||||||
|
signals = await port.getSignals();
|
||||||
|
assert_object_equals(signals, expectedSignals, 'CTS set');
|
||||||
|
|
||||||
|
expectedSignals.ringIndicator = true;
|
||||||
|
fakePort.simulateInputSignals(expectedSignals);
|
||||||
|
signals = await port.getSignals();
|
||||||
|
assert_object_equals(signals, expectedSignals, 'RI set');
|
||||||
|
|
||||||
|
expectedSignals.dataSetReady = true;
|
||||||
|
fakePort.simulateInputSignals(expectedSignals);
|
||||||
|
signals = await port.getSignals();
|
||||||
|
assert_object_equals(signals, expectedSignals, 'DSR set');
|
||||||
|
}, 'getSignals() returns the current state of input control signals');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
await port.open({baudRate: 9600});
|
||||||
|
|
||||||
|
fakePort.simulateInputSignalFailure(true);
|
||||||
|
await promise_rejects_dom(t, 'NetworkError', port.getSignals());
|
||||||
|
|
||||||
|
fakePort.simulateInputSignalFailure(false);
|
||||||
|
const expectedSignals = {
|
||||||
|
dataCarrierDetect: false,
|
||||||
|
clearToSend: false,
|
||||||
|
ringIndicator: false,
|
||||||
|
dataSetReady: false
|
||||||
|
};
|
||||||
|
const signals = await port.getSignals();
|
||||||
|
assert_object_equals(signals, expectedSignals);
|
||||||
|
|
||||||
|
await port.close();
|
||||||
|
}, 'getSignals() rejects on failure');
|
|
@ -0,0 +1,40 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
// Don't listen for 'disconnect' events on navigator.serial so we can listen
|
||||||
|
// for them on each SerialPort instance instead.
|
||||||
|
const eventWatcher = new EventWatcher(t, navigator.serial, ['connect']);
|
||||||
|
|
||||||
|
// Wait for getPorts() to resolve in order to ensure that the Mojo client
|
||||||
|
// interface has been configured.
|
||||||
|
let ports = await navigator.serial.getPorts();
|
||||||
|
assert_equals(ports.length, 0);
|
||||||
|
|
||||||
|
// Add ports one at a time so that we can map tokens to ports.
|
||||||
|
const token1 = fake.addPort();
|
||||||
|
const port1 = (await eventWatcher.wait_for(['connect'])).target;
|
||||||
|
const port1Watcher = new EventWatcher(t, port1, ['disconnect']);
|
||||||
|
|
||||||
|
const token2 = fake.addPort();
|
||||||
|
const port2 = (await eventWatcher.wait_for(['connect'])).target;
|
||||||
|
const port2Watcher = new EventWatcher(t, port2, ['disconnect']);
|
||||||
|
|
||||||
|
fake.removePort(token2);
|
||||||
|
const event1 = await port2Watcher.wait_for(['disconnect']);
|
||||||
|
assert_true(event1 instanceof Event);
|
||||||
|
assert_equals(event1.target, port2);
|
||||||
|
|
||||||
|
ports = await navigator.serial.getPorts();
|
||||||
|
assert_equals(ports.length, 1);
|
||||||
|
assert_equals(ports[0], port1);
|
||||||
|
|
||||||
|
fake.removePort(token1);
|
||||||
|
const event2 = await port1Watcher.wait_for(['disconnect']);
|
||||||
|
assert_true(event2 instanceof Event);
|
||||||
|
assert_equals(event2.target, port1);
|
||||||
|
|
||||||
|
ports = await navigator.serial.getPorts();
|
||||||
|
assert_equals(ports.length, 0);
|
||||||
|
}, 'A "disconnect" event is fired on ports when they are removed.');
|
|
@ -0,0 +1,95 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await port.open({baudRate: 9600});
|
||||||
|
return promise_rejects_dom(
|
||||||
|
t, 'InvalidStateError', port.open({baudRate: 9600}));
|
||||||
|
}, 'A SerialPort cannot be opened if it is already open.');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
const firstRequest = port.open({baudRate: 9600});
|
||||||
|
await promise_rejects_dom(
|
||||||
|
t, 'InvalidStateError', port.open({baudRate: 9600}));
|
||||||
|
await firstRequest;
|
||||||
|
}, 'Simultaneous calls to open() are disallowed.');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await promise_rejects_js(t, TypeError, port.open({}));
|
||||||
|
|
||||||
|
await Promise.all([-1, 0].map(
|
||||||
|
baudRate => {
|
||||||
|
return promise_rejects_js(t, TypeError, port.open({baudRate}))}));
|
||||||
|
}, 'Baud rate is required and must be greater than zero.');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await Promise.all([-1, 0, 6, 9].map(dataBits => {
|
||||||
|
return promise_rejects_js(
|
||||||
|
t, TypeError, port.open({baudRate: 9600, dataBits}));
|
||||||
|
}));
|
||||||
|
|
||||||
|
await[undefined, 7, 8].reduce(async (previousTest, dataBits) => {
|
||||||
|
await previousTest;
|
||||||
|
await port.open({baudRate: 9600, dataBits});
|
||||||
|
await port.close();
|
||||||
|
}, Promise.resolve());
|
||||||
|
}, 'Data bits must be 7 or 8');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await Promise.all([0, null, 'cats'].map(parity => {
|
||||||
|
return promise_rejects_js(
|
||||||
|
t, TypeError, port.open({baudRate: 9600, parity}),
|
||||||
|
`Should reject parity option "${parity}"`);
|
||||||
|
}));
|
||||||
|
|
||||||
|
await[undefined, 'none', 'even', 'odd'].reduce(
|
||||||
|
async (previousTest, parity) => {
|
||||||
|
await previousTest;
|
||||||
|
await port.open({baudRate: 9600, parity});
|
||||||
|
await port.close();
|
||||||
|
},
|
||||||
|
Promise.resolve());
|
||||||
|
}, 'Parity must be "none", "even" or "odd"');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await Promise.all([-1, 0, 3, 4].map(stopBits => {
|
||||||
|
return promise_rejects_js(
|
||||||
|
t, TypeError, port.open({baudRate: 9600, stopBits}));
|
||||||
|
}));
|
||||||
|
|
||||||
|
await[undefined, 1, 2].reduce(async (previousTest, stopBits) => {
|
||||||
|
await previousTest;
|
||||||
|
await port.open({baudRate: 9600, stopBits});
|
||||||
|
await port.close();
|
||||||
|
}, Promise.resolve());
|
||||||
|
}, 'Stop bits must be 1 or 2');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await promise_rejects_js(
|
||||||
|
t, TypeError, port.open({baudRate: 9600, bufferSize: -1}));
|
||||||
|
await promise_rejects_js(
|
||||||
|
t, TypeError, port.open({baudRate: 9600, bufferSize: 0}));
|
||||||
|
}, 'Buffer size must be greater than zero.');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
const bufferSize = 1 * 1024 * 1024 * 1024 /* 1 GiB */;
|
||||||
|
return promise_rejects_js(
|
||||||
|
t, TypeError, port.open({baudRate: 9600, bufferSize}));
|
||||||
|
}, 'Unreasonably large buffer sizes are rejected.');
|
|
@ -0,0 +1,69 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
await port.open({baudRate: 9600, bufferSize: 64});
|
||||||
|
|
||||||
|
const reader = port.readable.getReader();
|
||||||
|
const readPromise = reader.read();
|
||||||
|
await reader.cancel();
|
||||||
|
const {value, done} = await readPromise;
|
||||||
|
assert_true(done);
|
||||||
|
assert_equals(undefined, value);
|
||||||
|
|
||||||
|
await port.close();
|
||||||
|
}, 'Can cancel while reading');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
await port.open({baudRate: 9600, bufferSize: 64});
|
||||||
|
|
||||||
|
const reader = port.readable.getReader();
|
||||||
|
const closed = (async () => {
|
||||||
|
const {value, done} = await reader.read();
|
||||||
|
assert_true(done);
|
||||||
|
assert_equals(undefined, value);
|
||||||
|
reader.releaseLock();
|
||||||
|
await port.close();
|
||||||
|
assert_equals(port.readable, null);
|
||||||
|
})();
|
||||||
|
|
||||||
|
await reader.cancel();
|
||||||
|
await closed;
|
||||||
|
}, 'Can close while canceling');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
await port.open({baudRate: 9600, bufferSize: 64});
|
||||||
|
|
||||||
|
const reader = port.readable.getReader();
|
||||||
|
|
||||||
|
await fakePort.writable();
|
||||||
|
const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||||
|
await fakePort.write(data);
|
||||||
|
|
||||||
|
await reader.cancel();
|
||||||
|
await port.close();
|
||||||
|
}, 'Cancel discards a small amount of data waiting to be read');
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
// Select a buffer size smaller than the amount of data transferred.
|
||||||
|
await port.open({baudRate: 9600, bufferSize: 64});
|
||||||
|
|
||||||
|
const reader = port.readable.getReader();
|
||||||
|
|
||||||
|
await fakePort.writable();
|
||||||
|
const data = new Uint8Array(1024);
|
||||||
|
// Writing will fail because there was more data to send than could fit in the
|
||||||
|
// buffer and none of it was read.
|
||||||
|
const writePromise =
|
||||||
|
promise_rejects_dom(t, 'InvalidStateError', fakePort.write(data));
|
||||||
|
|
||||||
|
await reader.cancel();
|
||||||
|
await writePromise;
|
||||||
|
|
||||||
|
await port.close();
|
||||||
|
}, 'Cancel discards a large amount of data waiting to be read');
|
|
@ -0,0 +1,30 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
// Select a buffer size larger than the amount of data transferred.
|
||||||
|
await port.open({baudRate: 9600, bufferSize: 64});
|
||||||
|
|
||||||
|
const decoder = new TextDecoderStream();
|
||||||
|
const streamClosed = port.readable.pipeTo(decoder.writable);
|
||||||
|
const readable = decoder.readable.pipeThrough(new TransformStream())
|
||||||
|
.pipeThrough(new TransformStream())
|
||||||
|
.pipeThrough(new TransformStream())
|
||||||
|
.pipeThrough(new TransformStream());
|
||||||
|
const reader = readable.getReader();
|
||||||
|
|
||||||
|
await fakePort.writable();
|
||||||
|
fakePort.write(new TextEncoder().encode('Hello world!'));
|
||||||
|
|
||||||
|
const {value, done} = await reader.read();
|
||||||
|
assert_false(done);
|
||||||
|
assert_equals('Hello world!', value);
|
||||||
|
await reader.cancel('arbitrary reason');
|
||||||
|
await streamClosed.catch(reason => {
|
||||||
|
assert_equals('arbitrary reason', reason);
|
||||||
|
});
|
||||||
|
|
||||||
|
await port.close();
|
||||||
|
}, 'Stream closure is observable through a long chain of transforms');
|
|
@ -0,0 +1,17 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
await port.open({baudRate: 9600});
|
||||||
|
assert_true(port.readable instanceof ReadableStream);
|
||||||
|
|
||||||
|
const reader = port.readable.getReader();
|
||||||
|
await promise_rejects_js(t, TypeError, port.close());
|
||||||
|
|
||||||
|
reader.releaseLock();
|
||||||
|
await port.close();
|
||||||
|
assert_equals(port.readable, null);
|
||||||
|
}, 'Port cannot be closed while readable is locked');
|
|
@ -0,0 +1,25 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
// Select a buffer size smaller than the amount of data transferred.
|
||||||
|
await port.open({baudRate: 9600, bufferSize: 64});
|
||||||
|
|
||||||
|
const reader = port.readable.getReader();
|
||||||
|
|
||||||
|
await fakePort.writable();
|
||||||
|
const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||||
|
fakePort.write(data);
|
||||||
|
fakePort.simulateDisconnectOnRead();
|
||||||
|
|
||||||
|
const {value, done} = await reader.read();
|
||||||
|
assert_false(done);
|
||||||
|
compareArrays(data, value);
|
||||||
|
|
||||||
|
await promise_rejects_dom(t, 'NetworkError', reader.read());
|
||||||
|
assert_equals(port.readable, null);
|
||||||
|
|
||||||
|
await port.close();
|
||||||
|
}, 'Disconnect error closes readable and sets it to null');
|
|
@ -0,0 +1,23 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
// Select a buffer size smaller than the amount of data transferred.
|
||||||
|
await port.open({baudRate: 9600, bufferSize: 64});
|
||||||
|
|
||||||
|
const reader = port.readable.getReader();
|
||||||
|
|
||||||
|
await fakePort.writable();
|
||||||
|
const data = new Uint8Array(1024); // Much larger than bufferSize above.
|
||||||
|
for (let i = 0; i < data.byteLength; ++i)
|
||||||
|
data[i] = i & 0xff;
|
||||||
|
fakePort.write(data);
|
||||||
|
|
||||||
|
const value = await readWithLength(reader, data.byteLength);
|
||||||
|
compareArrays(data, value);
|
||||||
|
reader.releaseLock();
|
||||||
|
|
||||||
|
await port.close();
|
||||||
|
}, 'Can read a large amount of data');
|
|
@ -0,0 +1,21 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
|
||||||
|
assert_equals(port.readable, null);
|
||||||
|
|
||||||
|
await port.open({baudRate: 9600});
|
||||||
|
const readable = port.readable;
|
||||||
|
assert_true(readable instanceof ReadableStream);
|
||||||
|
|
||||||
|
await port.close();
|
||||||
|
assert_equals(port.readable, null);
|
||||||
|
|
||||||
|
const reader = readable.getReader();
|
||||||
|
const {value, done} = await reader.read();
|
||||||
|
assert_true(done);
|
||||||
|
assert_equals(value, undefined);
|
||||||
|
}, 'SerialPort.readable is set by open() and closes on port close');
|
|
@ -0,0 +1,52 @@
|
||||||
|
// META: script=/resources/test-only-api.js
|
||||||
|
// META: script=/serial/resources/common.js
|
||||||
|
// META: script=resources/automation.js
|
||||||
|
|
||||||
|
// ParityError is not (as of 2020/03/23) a valid DOMException, so cannot use
|
||||||
|
// promise_rejects_dom for it.
|
||||||
|
async function promise_rejects_with_parity_error(t, promise) {
|
||||||
|
return promise
|
||||||
|
.then(() => {
|
||||||
|
assert_false('Should have rejected');
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
assert_equals(e.constructor, DOMException);
|
||||||
|
assert_equals(e.name, 'ParityError');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_test(async (t, fake) => {
|
||||||
|
const {port, fakePort} = await getFakeSerialPort(fake);
|
||||||
|
// Select a buffer size smaller than the amount of data transferred.
|
||||||
|
await port.open({baudRate: 9600, bufferSize: 64});
|
||||||
|
|
||||||
|
let readable = port.readable;
|
||||||
|
let reader = readable.getReader();
|
||||||
|
|
||||||
|
await fakePort.writable();
|
||||||
|
const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||||
|
fakePort.write(data);
|
||||||
|
fakePort.simulateParityError();
|
||||||
|
|
||||||
|
let {value, done} = await reader.read();
|
||||||
|
assert_false(done);
|
||||||
|
compareArrays(data, value);
|
||||||
|
|
||||||
|
await promise_rejects_with_parity_error(t, reader.read());
|
||||||
|
assert_not_equals(port.readable, readable);
|
||||||
|
|
||||||
|
readable = port.readable;
|
||||||
|
assert_true(readable instanceof ReadableStream);
|
||||||
|
reader = port.readable.getReader();
|
||||||
|
|
||||||
|
await fakePort.writable();
|
||||||
|
fakePort.write(data);
|
||||||
|
|
||||||
|
({value, done} = await reader.read());
|
||||||
|
assert_false(done);
|
||||||
|
compareArrays(data, value);
|
||||||
|
reader.releaseLock();
|
||||||
|
|
||||||
|
await port.close();
|
||||||
|
assert_equals(port.readable, null);
|
||||||
|
}, 'Parity error closes readable and replaces it with a new stream');
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue