| <!doctype html> |
| <meta charset="utf-8"> |
| <title>Async Clipboard write should cancel the prior pending request</title> |
| <link rel="help" href="https://github.com/w3c/clipboard-apis/issues/161"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/resources/testdriver.js"></script> |
| <script src="/resources/testdriver-actions.js"></script> |
| <script src="/resources/testdriver-vendor.js"></script> |
| <script src="resources/user-activation.js"></script> |
| |
| <iframe width="50" height="50" id="same" src="resources/page.html"></iframe><br> |
| <iframe width="50" height="50" id="cross" src="https://{{hosts[alt][]}}:{{ports[https][1]}}/clipboard-apis/resources/page.html"></iframe><br> |
| <input value="Test"> |
| <script> |
| "use strict"; |
| |
| // Permissions are required in order to invoke navigator.clipboard functions in |
| // an automated test. |
| async function getPermissions() { |
| await tryGrantReadPermission(); |
| await tryGrantWritePermission() |
| await waitForUserActivation(); |
| } |
| |
| function waitForMessage(msg) { |
| return new Promise((resolve) => { |
| window.addEventListener("message", function handler(e) { |
| if (e.data == msg) { |
| window.removeEventListener("message", handler); |
| resolve(); |
| } |
| }); |
| }); |
| } |
| |
| function generateRandomString() { |
| return "random number: " + Math.random(); |
| } |
| |
| function testCancelPendingWrite(funcToMakeNewRequest, msg) { |
| promise_test(async t => { |
| await getPermissions(); |
| |
| // Create a pending write request which should be rejected after a new |
| // request is made. |
| let resolvePendingPromise; |
| let promise = navigator.clipboard.write([ |
| new ClipboardItem({ |
| "text/plain": new Promise((resolve) => { resolvePendingPromise = resolve; }), |
| }), |
| ]).catch(e => { return e; }); |
| |
| // Make a new request that should cancel the prior pending request. |
| let str = generateRandomString(); |
| await funcToMakeNewRequest(str); |
| |
| // Pending request should be rejected with NotAllowedError. |
| let error = await promise; |
| assert_not_equals(error, undefined); |
| assert_equals(error.name, "NotAllowedError"); |
| |
| // Resolve pending promise. |
| resolvePendingPromise(generateRandomString()); |
| // Check clipboard data. |
| assert_equals(await navigator.clipboard.readText(), str); |
| }, msg); |
| } |
| |
| testCancelPendingWrite(async (str) => { |
| // A new write request should cancel the prior pending request. |
| await navigator.clipboard.write([ |
| new ClipboardItem({ |
| "text/plain": str, |
| }), |
| ]).catch(() => { |
| assert_true(false, "should not fail"); |
| }); |
| }, "clipboard.write() should cancel the prior pending one (same document)"); |
| |
| testCancelPendingWrite(async (str) => { |
| // A new write should cancel the prior pending request. |
| const iframe = document.getElementById("same"); |
| iframe.contentWindow.postMessage(["write", str], "*"); |
| await waitForMessage("done"); |
| }, "clipboard.write() should cancel the prior pending one (same-origin iframe)"); |
| |
| testCancelPendingWrite(async (str) => { |
| // A new write should cancel the prior pending request. |
| const iframe = document.getElementById("cross"); |
| iframe.contentWindow.postMessage(["write", str], "*"); |
| await waitForMessage("done"); |
| }, "clipboard.write() should cancel the prior pending one (cross-origin iframe)"); |
| |
| testCancelPendingWrite(async (str) => { |
| const input = document.querySelector("input"); |
| input.value = str; |
| input.focus(); |
| input.select(); |
| |
| // A new copy action should cancel the prior pending request. |
| const modifier_key = navigator.platform.includes("Mac") ? "\uE03D" : "\uE009"; |
| await new test_driver.Actions().keyDown(modifier_key).keyDown("c").send(); |
| }, "copy action should cancel the prior pending clipboard.write() request"); |
| |
| </script> |