diff options
Diffstat (limited to 'testing/web-platform/tests/clipboard-apis')
60 files changed, 2181 insertions, 0 deletions
diff --git a/testing/web-platform/tests/clipboard-apis/META.yml b/testing/web-platform/tests/clipboard-apis/META.yml new file mode 100644 index 0000000000..ecbac54806 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/META.yml @@ -0,0 +1,3 @@ +spec: https://w3c.github.io/clipboard-apis/ +suggested_reviewers: + - garykac diff --git a/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-fail.tentative.https.html b/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-fail.tentative.https.html new file mode 100644 index 0000000000..8b1b42ec78 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-fail.tentative.https.html @@ -0,0 +1,123 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard web custom format write validation tests</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const customFormatArray = []; + const customFormatMap = {}; + for (let i = 0; i <= 100; i++) { + customFormatArray.push("web text/CustomFormat" + i); + const blobInput = new Blob(['input data'], {type: customFormatArray[i]}); + customFormatMap[customFormatArray[i]] = blobInput; + } + const clipboardItemInput = new ClipboardItem(customFormatMap); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for more than 100 custom formats'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'application/x-custom-format-clipboard-test-format-1'; + const format2 = 'application/x-custom-format-clipboard-test-format-2'; + const blobInput1 = new Blob(['input data 1'], {type: format1}); + const blobInput2 = new Blob(['input data 2'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1, [format2]: blobInput2}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for custom formats without web prefix'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'web '; + const format2 = 'web a'; + const blobInput1 = new Blob(['input data 1'], {type: format1}); + const blobInput2 = new Blob(['input data 2'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1, [format2]: blobInput2}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for custom formats with web prefix, but invalid MIME types'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'web text/plain'; + const format2 = 'text/custom'; + const blobInput1 = new Blob(['input data 1'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for custom format with web prefix, but different Blob type'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'web Text/plain'; + const format2 = 'text/plain'; + const blobInput1 = new Blob(['input data 1'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for custom format with different case than the Blob type'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'web text/plain'; + const format2 = 'Text/plain'; + const blobInput1 = new Blob(['input data 1'], {type: format1}); + const clipboardItemInput = new ClipboardItem( + {[format2]: blobInput1}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for invalid mime type that is different than the Blob type'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'web Text/plain'; + const format2 = 'web text/plain'; + const blobInput1 = new Blob(['input data 1'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for invalid mime type with web prefix and the Blob type'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'Text/plain'; + const format2 = 'text/plain'; + const blobInput1 = new Blob(['input data 1'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for custom format and Blob type with different case'); + +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read-web-prefix.tentative.https.html b/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read-web-prefix.tentative.https.html new file mode 100644 index 0000000000..9a6e5da6ff --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read-web-prefix.tentative.https.html @@ -0,0 +1,39 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard web custom format read/write test.</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'web text/plain'; + const format2 = 'web text/plain'; + const blobInput1 = new Blob(['input data 1'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + // This test can't verify clipboardItem.types, because its size and values + // are both platform-dependent. + + const blobOutput1 = await clipboardItem.getType(format1); + assert_equals(blobOutput1.type, format1); + const data1 = await (new Response(blobOutput1)).text(); + assert_equals(data1, 'input data 1'); +}, 'navigator.clipboard.write() for custom format and Blob type with web prefix'); + +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read-without-web-prefix.tentative.https.html b/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read-without-web-prefix.tentative.https.html new file mode 100644 index 0000000000..8b9d4de0a1 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read-without-web-prefix.tentative.https.html @@ -0,0 +1,39 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard web custom format write using Blob without web prefix test.</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'web text/plain'; + const format2 = 'text/plain'; + const blobInput1 = new Blob(['input data 1'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + // This test can't verify clipboardItem.types, because its size and values + // are both platform-dependent. + + const blobOutput1 = await clipboardItem.getType(format1); + assert_equals(blobOutput1.type, format1); + const data1 = await (new Response(blobOutput1)).text(); + assert_equals(data1, 'input data 1'); +}, 'navigator.clipboard.write() for custom format with web prefix, but Blob type without web prefix'); + +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read.tentative.https.html b/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read.tentative.https.html new file mode 100644 index 0000000000..a005f8c98f --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-custom-formats-write-read.tentative.https.html @@ -0,0 +1,47 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard custom write -> Async Clipboard custom read test</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + const format1 = 'web application/x-custom-format-clipboard-test-format-1'; + const format2 = 'web application/x-custom-format-clipboard-test-format-2'; + const blobInput1 = new Blob(['input data 1'], {type: format1}); + const blobInput2 = new Blob(['input data 2'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1, [format2]: blobInput2}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + + // Items should be readable on a custom format clipboard after custom format + // write. + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + // This test can't verify clipboardItem.types, because its size and values + // are both platform-dependent. + + const blobOutput1 = await clipboardItem.getType(format1); + assert_equals(blobOutput1.type, format1); + const data1 = await (new Response(blobOutput1)).text(); + assert_equals(data1, 'input data 1'); + + const blobOutput2 = await clipboardItem.getType(format2); + assert_equals(blobOutput2.type, format2); + const data2 = await (new Response(blobOutput2)).text(); + assert_equals(data2, 'input data 2'); +}, 'Verify write and read clipboard given 2 platform-neutral custom format inputs'); + +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-html-script-removal.https.html b/testing/web-platform/tests/clipboard-apis/async-html-script-removal.https.html new file mode 100644 index 0000000000..44c11add85 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-html-script-removal.https.html @@ -0,0 +1,60 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write ([text/html ClipboardItem]) -> readHtml (and remove scripts) tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; +// This function removes extra spaces between tags in html. For example, the +// following html: "<p> Hello </p> <body> World </body>" would turn into this +// html: "<p> Hello </p> <body> World </body>" +// We remove the extra spaces because in html they are considered equivalent, +// but when we are comparing for equality the spaces make a difference. +function reformatHtml(html) { + const parser = new DOMParser(); + const htmlString = + parser.parseFromString(html, 'text/html').documentElement.innerHTML; + const reformattedString = htmlString.replace(/\>\s*\</g, '> <'); + return reformattedString; +} + +// The string must be concatenated in this way because the html parser +// will recognize a script tag even in quotes as a real script tag. By +// splitting it up in this way we avoid that error. +const html_with_script = + '<title>Title of the document</title> <script>const a = 5;</scr' + + 'ipt> <p>Hello World</p>'; +const html_without_script = + '<title>Title of the document</title> <p>Hello World</p>'; +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + const blobInput = new Blob([html_with_script], {type: 'text/html'}); + const clipboardItem = new ClipboardItem({'text/html': blobInput}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItem]); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + + const html = clipboardItems[0]; + assert_equals(html.types.length, 1); + assert_equals(html.types[0], 'text/html'); + + const blobOutput = await html.getType('text/html'); + assert_equals(blobOutput.type, 'text/html'); + + const blobText = await (new Response(blobOutput)).text(); + + const outputHtml = reformatHtml(blobText); + const inputHtml = reformatHtml(html_without_script); + assert_equals(outputHtml, inputHtml); +}, 'Verify write and read clipboard with scripts removed given text/html: ' + + html_with_script); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-basics.https.html b/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-basics.https.html new file mode 100644 index 0000000000..4a11d5ac66 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-basics.https.html @@ -0,0 +1,154 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard input type validation tests</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> + +// Permissions are required in order to invoke navigator.clipboard functions in +// an automated test. +async function getPermissions() { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + await waitForUserActivation(); +} + +test(() => { + assert_not_equals(navigator.clipboard, undefined); + assert_true(navigator.clipboard instanceof Clipboard); + assert_equals(navigator.clipboard, navigator.clipboard); +}, 'navigator.clipboard exists'); + +promise_test(async t => { + await getPermissions(); + const text_plain = "This text was copied using `Clipboard.prototype.write`."; + const html_text = "<p style='color: red; font-style: oblique;'>Test</p>"; + await promise_rejects_dom(t, "NotAllowedError", navigator.clipboard.write([ + new ClipboardItem({ + "text/plain": text_plain, + "text/html" : html_text + }), + ])); + }, 'navigator.clipboard.write(Promise<DOMString>) fails'); + +promise_test(async () => { + await getPermissions(); + const blob = new Blob(['hello'], {type: 'text/plain'}); + const item = new ClipboardItem({'text/plain': blob}); + + await navigator.clipboard.write([item]); +}, 'navigator.clipboard.write([text/plain ClipboardItem]) succeeds'); + +promise_test(async t => { + await getPermissions(); + const blob1 = new Blob(['hello'], {type: 'text/plain'}); + const blob2 = new Blob(['world'], {type: 'text/plain'}); + + const item1 = new ClipboardItem({'text/plain': blob1}); + const item2 = new ClipboardItem({'text/plain': blob2}); + + await promise_rejects_dom(t, "NotAllowedError", + navigator.clipboard.write([item1, item2])); +}, 'navigator.clipboard.write([>1 ClipboardItems]) fails (not implemented)'); + +promise_test(async t => { + await getPermissions(); + await promise_rejects_js(t, TypeError, navigator.clipboard.write()); +}, 'navigator.clipboard.write() fails (expect [ClipboardItem])'); + +promise_test(async t => { + await getPermissions(); + await promise_rejects_js(t, TypeError, navigator.clipboard.write(null)); +}, 'navigator.clipboard.write(null) fails (expect [ClipboardItem])'); + +promise_test(async t => { + await getPermissions(); + await promise_rejects_js(t, TypeError, + navigator.clipboard.write('Bad string')); +}, 'navigator.clipboard.write(DOMString) fails (expect [ClipboardItem])'); + +promise_test(async t => { + await getPermissions(); + const blob = new Blob(['hello'], {type: 'text/plain'}); + await promise_rejects_js(t, TypeError, navigator.clipboard.write(blob)); +}, 'navigator.clipboard.write(Blob) fails (expect [ClipboardItem])'); + +promise_test(async () => { + await getPermissions(); + await navigator.clipboard.writeText('New clipboard text'); +}, 'navigator.clipboard.writeText(DOMString) succeeds'); + +promise_test(async t => { + await getPermissions(); + await promise_rejects_js(t, TypeError, + navigator.clipboard.writeText()); +}, 'navigator.clipboard.writeText() fails (expect DOMString)'); + +promise_test(async () => { + await getPermissions(); + const item = new ClipboardItem({'text/plain': 'test'}); + await navigator.clipboard.write([item]); +}, 'navigator.clipboard.write({string : DOMString}) succeeds'); + +promise_test(async () => { + await getPermissions(); + const fetched = await fetch('/clipboard-apis/resources/greenbox.png'); + const image = await fetched.blob(); + const item = new ClipboardItem({'image/png': image}); + + await navigator.clipboard.write([item]); +}, 'navigator.clipboard.write({string : image/png Blob}) succeeds'); + +promise_test(async() => { + await getPermissions(); + const fetched = await fetch('/clipboard-apis/resources/greenbox.png'); + const image = await fetched.blob(); + const item = new ClipboardItem({ + 'text/plain': new Blob(['first'], {type: 'text/plain'}), + 'image/png': image}); + + await navigator.clipboard.write([item]); +}, 'navigator.clipboard.write([text + png] succeeds'); + +promise_test(async t => { + await getPermissions(); + const item = new ClipboardItem({'image/png': 'not an image'}); + await promise_rejects_js(t, TypeError, navigator.clipboard.write([item])); +}, 'navigator.clipboard.write(image/png DOMString) fails'); + +promise_test(async () => { + await getPermissions(); + const result = await navigator.clipboard.read(); + assert_true(result instanceof Object); + assert_true(result[0] instanceof ClipboardItem); +}, 'navigator.clipboard.read() succeeds'); + +promise_test(async () => { + await getPermissions(); + const result = await navigator.clipboard.readText(); + assert_equals(typeof result, 'string'); +}, 'navigator.clipboard.readText() succeeds'); + +promise_test(async () => { + await getPermissions(); + const promise_blob = Promise.resolve(new Blob(['hello'], {type: 'text/plain'})); + const item = new ClipboardItem({'text/plain': promise_blob}); + + await navigator.clipboard.write([item]); +}, 'navigator.clipboard.write(Promise<Blob>) succeeds'); + +promise_test(async () => { + await getPermissions(); + const promise_text_blob = Promise.resolve(new Blob(['hello'], {type: 'text/plain'})); + const promise_html_blob = Promise.resolve(new Blob(["<p style='color: red; font-style: oblique;'>Test</p>"], {type: 'text/html'})); + const item = new ClipboardItem({'text/plain': promise_text_blob, 'text/html': promise_html_blob}); + + await navigator.clipboard.write([item]); +}, 'navigator.clipboard.write(Promise<Blob>s) succeeds'); + +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-read-resource-load.https.html b/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-read-resource-load.https.html new file mode 100644 index 0000000000..d1e3019e7f --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-read-resource-load.https.html @@ -0,0 +1,44 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard.read() should not trigger resource loading</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#dom-clipboard-read"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1315563"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> + +<body>Body needed for test_driver.click() +<p><button id="button">Put payload in the clipboard</button></p> +<div id="output"></div> + +<script> +button.onclick = () => document.execCommand('copy'); +document.oncopy = ev => { + ev.preventDefault(); + ev.clipboardData.setData( + 'text/html', + '<img src="https://example.com/oops">'); +}; + +promise_test(async test => { + let loadObserved = false; + const observer = new PerformanceObserver(() => loadObserved = true); + observer.observe({type: 'resource'}); + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.click(button); + + await waitForUserActivation(); + const items = await navigator.clipboard.read(); + const htmlBlob = await items[0].getType("text/html"); + const html = await htmlBlob.text(); + + assert_equals(html, '<img src="https://example.com/oops">'); + + // Allow resource loading to start asynchronously + await new Promise(resolve => test.step_timeout(resolve, 100)); + assert_false(loadObserved, 'Should not observe resource loading'); +}); +</script> +</body> diff --git a/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html b/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html new file mode 100644 index 0000000000..cc18367534 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html @@ -0,0 +1,48 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard.read() should sanitize text/html</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#dom-clipboard-read"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1315563"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> + +<body>Body needed for test_driver.click() +<p><button id="button">Put payload in the clipboard</button></p> +<div id="output"></div> + +<script> +let testFailed = false; +function fail() { + testFailed = true; +} + +button.onclick = () => document.execCommand('copy'); +document.oncopy = ev => { + ev.preventDefault(); + ev.clipboardData.setData( + 'text/html', + `<form><math><mtext></form><form><mglyph><xmp></math><img src=invalid onerror=fail()></xmp>`); +}; + +promise_test(async test => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.click(button); + + await waitForUserActivation(); + const items = await navigator.clipboard.read(); + const htmlBlob = await items[0].getType("text/html"); + const html = await htmlBlob.text(); + + // This inserts an image with `onerror` handler if `html` is not properly sanitized + output.innerHTML = html; + + // Allow the 'error' event to be dispatched asynchronously + await new Promise(resolve => test.step_timeout(resolve, 100)); + + assert_false(testFailed); +}); +</script> +</body> diff --git a/testing/web-platform/tests/clipboard-apis/async-promise-write-blobs-read-blobs.https.html b/testing/web-platform/tests/clipboard-apis/async-promise-write-blobs-read-blobs.https.html new file mode 100644 index 0000000000..12184c92e0 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-promise-write-blobs-read-blobs.https.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write blobs -> read blobs with promise tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> + +<script> +async function loadBlob(fileName) { + const fetched = await fetch(fileName); + return await fetched.blob(); +} + +promise_test(async t => { + const promise1 = new Promise((resolve, reject) => { + resolve(loadBlob('resources/greenbox.png')); + }); + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const blobText = new Blob(['test text'], {type: 'text/plain'}); + + const clipboardItemInput = new ClipboardItem( + {'text/plain' : blobText, 'image/png' : promise1}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + + assert_equals(clipboardItem.types.length, 2); + const blobTextOutput = await clipboardItem.getType('text/plain'); + const blobImageOutput = await clipboardItem.getType('image/png'); + assert_equals(blobTextOutput.type, 'text/plain'); + assert_equals(blobImageOutput.type, 'image/png'); +}, 'Verify write and read clipboard (multiple types) with promise to Blobs'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-svg-script-removal.https.html b/testing/web-platform/tests/clipboard-apis/async-svg-script-removal.https.html new file mode 100644 index 0000000000..292d100b2f --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-svg-script-removal.https.html @@ -0,0 +1,61 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write ([image/svg+xml ClipboardItem]) -> readSvg (and remove scripts) tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; +// This function removes extra spaces between tags in svg. For example, the +// following svg: "<svg> <g> </g> </svg>" would turn into this +// svg: "<svg> <g> </g> </svg>" +// We remove the extra spaces because in svg they are considered equivalent, +// but when we are comparing for equality the spaces make a difference. +function reformatSvg(svg) { + const parser = new DOMParser(); + const svgString = + parser.parseFromString(svg, 'text/html').documentElement.innerHTML; + const reformattedString = svgString.replace(/\>\s*\</g, '> <'); + return reformattedString; +} + +// The string must be concatenated in this way because the html parser +// will recognize a script tag even in quotes as a real script tag. By +// splitting it up in this way we avoid that error. +const svg_with_script = + `<svg> <script>const a = 5;</scr' + 'ipt> + <a href="javascript:alert(2)"> test </a> </svg>`; +const svg_without_script = + `<svg> </svg>`; +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + const blobInput = new Blob([svg_with_script], {type: 'image/svg+xml'}); + const clipboardItem = new ClipboardItem({'image/svg+xml': blobInput}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItem]); + await waitForUserActivation(); + const clipboardItems = + await navigator.clipboard.read({type: 'image/svg+xml'}); + + const svg = clipboardItems[0]; + assert_equals(svg.types.length, 1); + assert_equals(svg.types[0], 'image/svg+xml'); + + const blobOutput = await svg.getType('image/svg+xml'); + assert_equals(blobOutput.type, 'image/svg+xml'); + + const blobText = await (new Response(blobOutput)).text(); + + const outputSvg = reformatSvg(blobText); + const inputSvg = reformatSvg(svg_without_script); + assert_equals(outputSvg, inputSvg); +}, 'Verify write and read clipboard with scripts removed given image/svg+xml: ' + + svg_with_script); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-unsanitized-html-formats-write-read.tentative.https.html b/testing/web-platform/tests/clipboard-apis/async-unsanitized-html-formats-write-read.tentative.https.html new file mode 100644 index 0000000000..ffe6a31c2a --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-unsanitized-html-formats-write-read.tentative.https.html @@ -0,0 +1,72 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard unsanitized HTML write -> Async Clipboard unsanitized HTML read test</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; + +// This function removes extra spaces between tags in html. For example, the +// following html: "<p> Hello </p> <body> World </body>" would turn into this +// html: "<p> Hello </p> <body> World </body>" +// We remove the extra spaces because in html they are considered equivalent, +// but when we are comparing for equality the spaces make a difference. +function reformatHtml(html) { + const parser = new DOMParser(); + const htmlString = + parser.parseFromString(html, 'text/html').documentElement.innerHTML; + const reformattedString = htmlString.replace(/\>\s*\</g, '> <'); + return reformattedString; +} + +// Writes a payload with custom content and checks to ensure the correct data +// was written successfully. +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + // Create and write unsanitized version of standard HTML and custom formats. + const format1 = 'text/html'; + const format2 = 'web text/html'; + const textInput = '<style>p {color:blue}</style><p>Hello World</p>'; + const blobInput1 = new Blob([textInput], {type: format1}); + const blobInput2 = new Blob([textInput], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1, [format2]: blobInput2}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + + // Read unsanitized version of HTML format. + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + + const blobOutput1 = await clipboardItem.getType(format1); + assert_equals(blobOutput1.type, format1); + const data1 = await (new Response(blobOutput1)).text(); + const outputHtml = reformatHtml(data1); + const expectedHtml = '<p style="color: blue; font-size: medium; font-style: normal; ' + + 'font-variant-ligatures: normal; font-variant-caps: normal; ' + + 'font-weight: 400; letter-spacing: normal; orphans: 2; ' + + 'text-align: start; text-indent: 0px; text-transform: none; '+ + 'white-space: normal; widows: 2; word-spacing: 0px; ' + + '-webkit-text-stroke-width: 0px; text-decoration-thickness: initial; ' + + 'text-decoration-style: initial; text-decoration-color: initial;">' + + 'Hello World</p>'; + const inputHtml = reformatHtml(expectedHtml); + assert_equals(outputHtml, inputHtml); + + const blobOutput2 = await clipboardItem.getType(format2); + assert_equals(blobOutput2.type, format2); + const data2 = await (new Response(blobOutput2)).text(); + assert_equals(data2, textInput); +}, 'Verify write and read unsanitized content to the clipboard given text/html format as input'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html b/testing/web-platform/tests/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html new file mode 100644 index 0000000000..1c5638ca0a --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html @@ -0,0 +1,52 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard unsanitized write -> Async Clipboard unsanitized read test</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; + +// Writes a payload with custom content and checks to ensure the correct data +// was written successfully. +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const dataToWrite = 'Test text.'; + const format1 = 'web text/plain'; + const format2 = 'text/plain'; + + const blobInput1 = new Blob([dataToWrite], {type: format1}); + const blobInput2 = new Blob([dataToWrite], {type: format2}); + // Blob types are automatically converted to lower-case. + assert_equals(blobInput1.type, format1.toLowerCase()); + assert_equals(blobInput2.type, format2.toLowerCase()); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1, [format2]: blobInput2}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + + // Items should be readable on a system clipboard after custom format write. + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + + const blobOutput1 = await clipboardItem.getType(format1); + assert_equals(blobOutput1.type, format1); + const data1 = await (new Response(blobOutput1)).text(); + assert_equals(data1, dataToWrite); + + // These examples use native text formats, so these formats should be + // accessible as text. + await waitForUserActivation(); + const textOutput = await navigator.clipboard.readText(); + assert_equals(textOutput, dataToWrite); +}, 'Verify write and read unsanitized content to the clipboard given standard and custom formats as input'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-write-blobs-read-blobs.https.html b/testing/web-platform/tests/clipboard-apis/async-write-blobs-read-blobs.https.html new file mode 100644 index 0000000000..8bec558b2b --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-write-blobs-read-blobs.https.html @@ -0,0 +1,48 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write blobs -> read blobs tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> + +<script> +async function loadBlob(fileName) { + const fetched = await fetch(fileName); + return await fetched.blob(); +} + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const blobText = new Blob(['test text'], {type: 'text/plain'}); + const blobImage = await loadBlob('resources/greenbox.png'); + + assert_equals(blobText.type, 'text/plain'); + assert_equals(blobImage.type, 'image/png'); + + const clipboardItemInput = new ClipboardItem( + {'text/plain' : blobText, 'image/png' : blobImage}); + + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + + assert_equals(clipboardItem.types.length, 2); + const blobTextOutput = await clipboardItem.getType('text/plain'); + const blobImageOutput = await clipboardItem.getType('image/png'); + assert_equals(blobTextOutput.type, 'text/plain'); + assert_equals(blobImageOutput.type, 'image/png'); +}, 'Verify write and read clipboard (multiple types)'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-write-html-read-html.https.html b/testing/web-platform/tests/clipboard-apis/async-write-html-read-html.https.html new file mode 100644 index 0000000000..ec1817c027 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-write-html-read-html.https.html @@ -0,0 +1,62 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write ([text/html ClipboardItem]) -> readHtml tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; +// This function removes extra spaces between tags in html. For example, the +// following html: "<p> Hello </p> <body> World </body>" would turn into this +// html: "<p> Hello </p> <body> World </body>" +// We remove the extra spaces because in html they are considered equivalent, +// but when we are comparing for equality the spaces make a difference. +function reformatHtml(html) { + const parser = new DOMParser(); + const htmlString = + parser.parseFromString(html, 'text/html').documentElement.innerHTML; + const reformattedString = htmlString.replace(/\>\s*\</g, '> <'); + return reformattedString; +} + +async function readWriteTest(textInput) { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + const blobInput = new Blob([textInput], {type: 'text/html'}); + const clipboardItem = new ClipboardItem({'text/html': blobInput}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItem]); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read({type: 'text/html'}); + + const html = clipboardItems[0]; + assert_equals(html.types.length, 1); + assert_equals(html.types[0], 'text/html'); + + const blobOutput = await html.getType('text/html'); + assert_equals(blobOutput.type, 'text/html'); + + const blobText = await (new Response(blobOutput)).text(); + + const outputHtml = reformatHtml(blobText); + const inputHtml = reformatHtml(textInput); + assert_equals(outputHtml, inputHtml); +} +const testCases = [`<!doctype html> <html> <head> <title>Title of the + document</title> </head> <body> <p>Hello World</p> + </body> </html>`, + '<title>Title of the document</title> <p>Hello World</p>']; + +promise_test(async t => { + for (const testCase of testCases) { + await readWriteTest(testCase); + } +}, 'Verify read and write of some text/html content'); + +</script> diff --git a/testing/web-platform/tests/clipboard-apis/async-write-image-read-image.https.html b/testing/web-platform/tests/clipboard-apis/async-write-image-read-image.https.html new file mode 100644 index 0000000000..e10b69d824 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-write-image-read-image.https.html @@ -0,0 +1,85 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write [image/png ClipboardItem] -> + read [image/png ClipboardItem] tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<body>Body needed for test_driver.click() +<p> + <p>The bottom image should display the same image as the top image.</p> + <p>Original Image:</p> + <image id="image-to-copy" width="20" height="20" + src="resources/greenbox.png"></image> + <p>Image after copy/paste:</p> + <image id="image-on-clipboard"></image> + <canvas id="canvas" width="20" height="20"></canvas> +</p> + +<script> +// Must compare a bitmap as opposed to simply blob data, because an encoded +// image may have different contents depending on encoder. +async function getBitmapString(blob) { + const imageBitmap = await createImageBitmap(blob); + const canvas = document.getElementById('canvas'); + const ctx = canvas.getContext('2d'); + + ctx.drawImage(imageBitmap, 0,0); + + let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + ctx.clearRect(0, 0, canvas.width, canvas.height); + return imageData.data.toString(); +}; + +async function loadBlob(fileName) { + const fetched = await fetch(fileName); + return await fetched.blob(); +} + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const blobInput = await loadBlob('resources/greenbox.png'); + + assert_equals(blobInput.type, 'image/png'); + const clipboardItemInput = new ClipboardItem({'image/png' : blobInput}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + assert_equals(clipboardItem.types.length, 1); + const blobOutput = await clipboardItem.getType('image/png'); + assert_equals(blobOutput.type, 'image/png'); + + document.getElementById('image-on-clipboard').src = + window.URL.createObjectURL(blobOutput); + + const comparableInput = await getBitmapString(blobInput); + const comparableOutput = await getBitmapString(blobOutput); + + assert_equals(comparableOutput, comparableInput); +}, 'Verify write and read clipboard [image/png Blob]'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const invalidPngBlob = new Blob(['this text is not a valid png image'], + {type: 'image/png'}); + const clipboardItemInput = new ClipboardItem({'image/png' : invalidPngBlob}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'DataError', + navigator.clipboard.write([clipboardItemInput])); +}, 'Verify write error on malformed data [image/png ClipboardItem]'); +</script> +</body> diff --git a/testing/web-platform/tests/clipboard-apis/async-write-svg-read-svg.https.html b/testing/web-platform/tests/clipboard-apis/async-write-svg-read-svg.https.html new file mode 100644 index 0000000000..42f6c547b2 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/async-write-svg-read-svg.https.html @@ -0,0 +1,60 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write ([image/svg+xml ClipboardItem]) -> read and write svg tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/user-activation.js"></script> +<script> +'use strict'; +// This function removes extra spaces between tags in svg. For example, the +// following html: "<svg> <g> </g> </svg>" would turn into this +// html: "<svg> <g> </g> </svg>" +// We remove the extra spaces because in svg they are considered equivalent, +// but when we are comparing for equality the spaces make a difference. +function reformatSvg(svg) { + const parser = new DOMParser(); + const svgString = + parser.parseFromString(svg, 'text/html').documentElement.innerHTML; + const reformattedString = svgString.replace(/\>\s*\</g, '> <'); + return reformattedString; +} + +async function readWriteTest(textInput) { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + const blobInput = new Blob([textInput], {type: 'image/svg+xml'}); + const clipboardItem = new ClipboardItem({'image/svg+xml': blobInput}); + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItem]); + await waitForUserActivation(); + const clipboardItems = + await navigator.clipboard.read({type: 'image/svg+xml'}); + + const svg = clipboardItems[0]; + assert_equals(svg.types.length, 1); + assert_equals(svg.types[0], 'image/svg+xml'); + + const blobOutput = await svg.getType('image/svg+xml'); + assert_equals(blobOutput.type, 'image/svg+xml'); + + const blobText = await (new Response(blobOutput)).text(); + const outputSvg = reformatSvg(blobText); + const inputSvg = reformatSvg(textInput); + assert_equals(outputSvg, inputSvg); +} +const testCases = ['<svg></svg>', + '<svg> <circle cx="50" cy="50" r="40" /> </svg>']; + +promise_test(async t => { + for (const testCase of testCases) { + await readWriteTest(testCase); + } +}, 'Verify read and write of some image/svg+xml content'); + +</script> diff --git a/testing/web-platform/tests/clipboard-apis/clipboard-events-synthetic.html b/testing/web-platform/tests/clipboard-apis/clipboard-events-synthetic.html new file mode 100644 index 0000000000..8786829752 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/clipboard-events-synthetic.html @@ -0,0 +1,32 @@ +<!doctype html> +<title>synthetic clipboard events should not be composed</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-copy"> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-cut"> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-paste"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +const EVENTS = [ 'copy', 'cut', 'paste' ]; + +function testEvent(eventName, init, composed_flag_expectation, testName) { + async_test(test => { + document.addEventListener(eventName, test.step_func_done(e => { + assert_false(e.isTrusted, `synthetic ${eventName} event is untrusted`); + assert_equals(e.composed, composed_flag_expectation, + `composed flag should be ${composed_flag_expectation}`); + })); + const event = new ClipboardEvent(eventName, init); + document.dispatchEvent(event); + }, testName); +} + +EVENTS.forEach(name => { + testEvent(name, { bubbles: true, cancellable: true }, false, + `Unspecified synthetic ${name} event should not be composed.`); + testEvent(name, { bubbles: true, cancelable: true, composed: true }, true, + `Synthetic ${name} event can be explicitly composed.`); + testEvent(name, { bubbles: true, cancelable: true, composed: false }, false, + `Synthetic ${name} event can be explicitly uncomposed.`); +}); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/clipboard-file-manual.html b/testing/web-platform/tests/clipboard-apis/clipboard-file-manual.html new file mode 100644 index 0000000000..e934f2fd0d --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/clipboard-file-manual.html @@ -0,0 +1,87 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Clipboard: DataTransfer File manual test</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#to-fire-a-clipboard-event"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +#pastewrapper { + display: block; + width: 400px; + height: 200px; + position: relative; + padding: 50px 0 0 100px; +} +#pastezone { + display: block; + border: 1px solid black; + width: 200px; + height: 100px; +} +</style> +<p> + Please download <a download href="resources/copied-file.txt">this file</a>, + and copy and paste it into the box below. +</p> + +<div id="pastewrapper"> + <div id="pastezone"> + Paste Here + </div> +</div> + +<script> +'use strict'; + +const pasteWrapper = document.querySelector('#pastewrapper'); +const pasteZone = document.querySelector('#pastezone'); + +const pastePromise = new Promise((resolve, reject) => { + pasteZone.onpaste = event => { + event.preventDefault(); + + // Copy the information out of the DataTransfer instance before it is + // neutered when the event handler exits. + const dataTransfer = event.clipboardData; + const items = Array.from(dataTransfer.items).map(item => { + return {kind: item.kind, type: item.type, file: item.getAsFile() }; + }); + resolve({ types: dataTransfer.types, files: dataTransfer.files, items }); + }; +}); + +promise_test(async () => { + const dataTransfer = await pastePromise; + assert_true(dataTransfer.types.includes('Files')); +}, 'DataTransfer.types in paste file'); + +promise_test(async () => { + const dataTransfer = await pastePromise; + assert_equals( + dataTransfer.files.length, 1, + 'DataTransfer.files should have one element'); + const file = dataTransfer.files[0]; + assert_true( + file instanceof File, + 'DataTransfer.files[0] should be a File instance'); + assert_equals(file.name, 'copied-file.txt'); + assert_equals(file.type, 'text/plain'); + assert_equals(file.size, 21); + assert_equals(await file.text(), 'copied-file-contents\n'); +}, 'DataTransfer.files in paste'); + +promise_test(async () => { + const dataTransfer = await pastePromise; + const items = dataTransfer.items.filter(i => i.kind === 'file'); + assert_equals(items.length, 1, + 'DataTransfer.items[kind="file"] should have 1 element'); + const item = items[0]; + assert_true( + item.file instanceof File, + 'DataTransfer.items[0] should be a File instance'); + assert_equals(item.file.name, 'copied-file.txt'); + assert_equals(item.file.type, 'text/plain'); + assert_equals(item.file.size, 21); + assert_equals(await item.file.text(), 'copied-file-contents\n'); +}, 'DataTransfer.items in paste'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/clipboard-item.https.html b/testing/web-platform/tests/clipboard-apis/clipboard-item.https.html new file mode 100644 index 0000000000..9ed6f583bd --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/clipboard-item.https.html @@ -0,0 +1,98 @@ +<!doctype html> +<meta charset="utf-8"> +<title>ClipboardItem tests</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + +const blob = new Blob(['hello'], {type: 'text/plain'}); +const blob2 = new Blob(['this should work'], {type: 'not a/real type'}); + +test(() => { + new ClipboardItem({'text/plain': blob}); + new ClipboardItem({'text/plain': blob, 'not a/real type': blob2}); +}, "ClipboardItem({string, Blob}) succeeds with different types"); + +test(() => { + new ClipboardItem({'text/plain': blob}, {}); +}, "ClipboardItem() succeeds with empty options"); + +test(() => { + assert_throws_js(TypeError, () => {new ClipboardItem({});}); +}, "ClipboardItem({}) fails with empty dictionary input"); + +test(() => { + assert_throws_js(TypeError, () => {new ClipboardItem(blob);}); +}, "ClipboardItem(Blob) fails"); + +test(() => { + assert_throws_js(TypeError, () => {new ClipboardItem(null);}); +}, "ClipboardItem() fails with null input"); + +test(() => { + assert_throws_js(TypeError, () => {new ClipboardItem();}); +}, "ClipboardItem() fails with no input"); + +test(() => { + const item = new ClipboardItem({'text/plain': blob}); + const types = item.types; + assert_equals(types.length, 1); + assert_equals(types[0], 'text/plain'); + const item2 = + new ClipboardItem({'text/plain': blob, 'not a/real type': blob2}); + const types2 = item2.types; + assert_equals(types2.length, 2); + assert_equals(types2[0], 'text/plain'); + assert_equals(types2[1], 'not a/real type'); +}, "types() returns correct values"); + +promise_test(async () => { + const item = + new ClipboardItem({'text/plain': blob, 'not a/real type': blob2}); + + const blobOutput = await item.getType('text/plain'); + assert_true(blobOutput.type.includes('text/plain')); + const text = await (new Response(blobOutput)).text(); + + assert_equals('hello', text); +}, "getType(DOMString valid type) succeeds with correct output"); + +promise_test(async () => { + const item = + new ClipboardItem({'text/plain': blob, 'not a/real type': blob2}); + + const blobOutput = await item.getType('not a/real type'); + assert_true(blobOutput.type.includes('not a/real type')); + const text = await (new Response(blobOutput)).text(); + + assert_equals('this should work', text); +}, "getType(DOMString invalid type) succeeds with correct output"); + +promise_test(async t => { + const item = + new ClipboardItem({'text/plain': blob, 'not a/real type': blob2}); + promise_rejects_dom(t, "NotFoundError", item.getType('type not in item')); + promise_rejects_dom(t, "NotFoundError", item.getType('text/plain:subtype')); +}, "getType(DOMString type) rejects correctly when querying for missing type"); + +promise_test(async () => { + const item = + new ClipboardItem({'text/plain': 'abc', 'not a/real type': 'xxx'}); + const blob = await item.getType('text/plain'); + assert_equals(blob.type, 'text/plain'); + + const text = await (new Response(blob)).text(); + assert_equals(text, 'abc'); +}, "getType(DOMString valid type) converts DOMString to Blob"); + +promise_test(async () => { + const item = + new ClipboardItem({'text/plain': 'abc', 'not a/real type': 'xxx'}); + const blob = await item.getType('not a/real type'); + assert_equals(blob.type, 'not a/real type'); + + const text = await (new Response(blob)).text(); + assert_equals(text, 'xxx'); +}, "getType(DOMString invalid type) converts DOMString to Blob"); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/detached-iframe/clipboard-on-detached-iframe.https.html b/testing/web-platform/tests/clipboard-apis/detached-iframe/clipboard-on-detached-iframe.https.html new file mode 100644 index 0000000000..5eb58e3213 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/detached-iframe/clipboard-on-detached-iframe.https.html @@ -0,0 +1,26 @@ +<!doctype html> +<meta charset=utf-8> +<title>Clipboard API on detached iframe</title> +<link rel='help' href='https://w3c.github.io/clipboard-apis/#async-clipboard-api'> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<iframe id="iframe"></iframe> +<script> +'use strict'; + +promise_test(async () => { + const iframe = document.getElementById('iframe'); + const iframeNavigator = iframe.contentWindow.navigator; + assert_not_equals(navigator.clipboard, null, + "parent frame's clipboard should exist with iframe attached"); + assert_not_equals(iframeNavigator.clipboard, null, + "attached child iframe's clipboard should exist"); + + iframe.parentNode.removeChild(iframe); + assert_not_equals(navigator.clipboard, null, + "parent frame's clipboard should exist with iframe detached"); + assert_not_equals(iframeNavigator.clipboard, null, + "detached child iframe's clipboard should still exist"); +}, 'Verify navigator.clipboard behavior in detached frames'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/detached-iframe/read-on-detaching-iframe.https.html b/testing/web-platform/tests/clipboard-apis/detached-iframe/read-on-detaching-iframe.https.html new file mode 100644 index 0000000000..8e8e015aa0 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/detached-iframe/read-on-detaching-iframe.https.html @@ -0,0 +1,34 @@ +<!doctype html> +<meta charset=utf-8> +<title>navigator.clipboard read on detaching iframe</title> +<link rel='help' href='https://w3c.github.io/clipboard-apis/#async-clipboard-api'> +<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> +<iframe id="iframe"></iframe> +<script> +'use strict'; + +promise_test(async t => { + // This tests proper behavior on a detaching iframe. text/plain is chosen for + // simplicity, and the test should fail the same way no matter what the input + // type is. + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const iframe = document.getElementById('iframe'); + const iframeClipboard = iframe.contentWindow.navigator.clipboard; + const blobInput = new Blob(['test string'], {type: 'text/plain'}); + const clipboardItemInput = new ClipboardItem({'text/plain': blobInput}); + // Clipboard API must only be available in focused documents. + // reference: https://www.w3.org/TR/clipboard-apis/#privacy-async + iframe.focus(); + + // An iframe detaching while writing to the clipboard should fail, but not + // crash. The lack of await here means that the iframe will detach while the + // write operation is running. + iframeClipboard.read([clipboardItemInput]); + iframe.parentNode.removeChild(iframe); +}, 'Verify read fails on detaching iframe'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/detached-iframe/write-on-detaching-iframe.https.html b/testing/web-platform/tests/clipboard-apis/detached-iframe/write-on-detaching-iframe.https.html new file mode 100644 index 0000000000..c6913d9e9f --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/detached-iframe/write-on-detaching-iframe.https.html @@ -0,0 +1,34 @@ +<!doctype html> +<meta charset=utf-8> +<title>navigator.clipboard write on detaching iframe</title> +<link rel='help' href='https://w3c.github.io/clipboard-apis/#async-clipboard-api'> +<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> +<iframe id="iframe"></iframe> +<script> +'use strict'; + +promise_test(async t => { + // This tests proper behavior on a detaching iframe. text/plain is chosen for + // simplicity, and the test should fail the same way no matter what the input + // type is. + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const iframe = document.getElementById('iframe'); + const iframeClipboard = iframe.contentWindow.navigator.clipboard; + const blobInput = new Blob(['test string'], {type: 'text/plain'}); + const clipboardItemInput = new ClipboardItem({'text/plain': blobInput}); + // Clipboard API must only be available in focused documents. + // reference: https://www.w3.org/TR/clipboard-apis/#privacy-async + iframe.focus(); + + // An iframe detaching while writing to the clipboard should fail, but not + // crash. The lack of await here means that the iframe will detach while the + // write operation is running. + iframeClipboard.write([clipboardItemInput]); + iframe.parentNode.removeChild(iframe); +}, 'Verify write fails on detaching iframe'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/detached-iframe/write-read-on-detached-iframe.https.html b/testing/web-platform/tests/clipboard-apis/detached-iframe/write-read-on-detached-iframe.https.html new file mode 100644 index 0000000000..b21e6b20bc --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/detached-iframe/write-read-on-detached-iframe.https.html @@ -0,0 +1,44 @@ +<!doctype html> +<meta charset=utf-8> +<title>navigator.clipboard read and write on detached iframe</title> +<link rel='help' href='https://w3c.github.io/clipboard-apis/#async-clipboard-api'> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<iframe id="iframe"></iframe> +<script> +'use strict'; + +promise_test(async t => { + // This tests proper behavior on a detaching iframe. text/plain is chosen for + // simplicity, and the test should fail the same way no matter what the input + // type is. + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const iframe = document.getElementById('iframe'); + const iframeClipboard = iframe.contentWindow.navigator.clipboard; + const blobInput = new Blob(['test string'], {type: 'text/plain'}); + const clipboardItemInput = new ClipboardItem({'text/plain': blobInput}); + await waitForUserActivation(); + // Clipboard API must only be available in focused documents. + // reference: https://www.w3.org/TR/clipboard-apis/#privacy-async + iframe.focus(); + + // Writing and reading should succeed on same-origin iframes. + await iframeClipboard.write([clipboardItemInput]); + const readResultAttached = await iframeClipboard.read(); + assert_not_equals(readResultAttached, undefined); + assert_equals(readResultAttached.length, 1, + 'attached iframes should be able to read and write normally'); + + iframe.parentNode.removeChild(iframe); + // Writing onto a detached iframe's clipboard should fail, but not crash. + await iframeClipboard.write([clipboardItemInput]); + const readResultDetached = await iframeClipboard.read(); + assert_equals(readResultDetached, undefined, + 'reading from detached iframes should output undefined'); +}, 'Verify read and write fail on detached iframe'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/detached-iframe/writeText-readText-on-detached-iframe.https.html b/testing/web-platform/tests/clipboard-apis/detached-iframe/writeText-readText-on-detached-iframe.https.html new file mode 100644 index 0000000000..24fa586fc7 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/detached-iframe/writeText-readText-on-detached-iframe.https.html @@ -0,0 +1,40 @@ +<!doctype html> +<meta charset=utf-8> +<title>navigator.clipboard readText and writeText on detached iframe</title> +<link rel='help' href='https://w3c.github.io/clipboard-apis/#async-clipboard-api'> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<iframe id="iframe"></iframe> +<script> +'use strict'; + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const iframe = document.getElementById('iframe'); + await waitForUserActivation(); + // Clipboard API must only be available in focused documents. + // reference: https://www.w3.org/TR/clipboard-apis/#privacy-async + iframe.focus(); + const iframeClipboard = iframe.contentWindow.navigator.clipboard; + + // Writing and reading should succeed on same-origin iframes. + const attachedWriteText = 'attached write text' + await iframeClipboard.writeText(attachedWriteText); + const attachedWriteResult = await iframeClipboard.readText(); + assert_equals(attachedWriteResult, attachedWriteText, + 'attached iframes should be able to readText and writeText normally'); + + iframe.parentNode.removeChild(iframe); + // Writing onto a detached iframe's clipboard should fail, but not crash. + const detachedWriteText = 'detached write text'; + await iframeClipboard.writeText(detachedWriteText); + const readResultDetached = await iframeClipboard.readText(); + assert_equals(readResultDetached, undefined, + 'reading from detached iframes should output undefined'); +}, 'Verify readText and writeText fails on detached iframe'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/events/copy-event.html b/testing/web-platform/tests/clipboard-apis/events/copy-event.html new file mode 100644 index 0000000000..c8c0593a98 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/events/copy-event.html @@ -0,0 +1,33 @@ +<!doctype html> +<title>The copy event</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-copy"> +<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> +<div id=log></div> +<button id="copy">Trigger copy</button> +<input id="copyTarget" value="this text should be copied"> +<script> +async_test(t => { + let button = document.getElementById("copy"); + + button.addEventListener("click", function(e) { + let input = document.getElementById("copyTarget"); + input.focus(); + input.select(); + document.execCommand("copy"); + }); + + document.oncopy = t.step_func_done(event => { + // Nothing can be asserted about the event target until + // https://github.com/w3c/clipboard-apis/issues/70 is resolved. + // assert_equals(event.target, document.body, 'event.target'); + assert_true(event.isTrusted, 'event.isTrusted'); + assert_true(event.composed, 'event.composed'); + }); + + test_driver.click(button); +}); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/events/cut-event-manual.html b/testing/web-platform/tests/clipboard-apis/events/cut-event-manual.html new file mode 100644 index 0000000000..72c11ec3b9 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/events/cut-event-manual.html @@ -0,0 +1,19 @@ +<!doctype html> +<title>The cut event</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-cut"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<input value="Select and cut any part of this text to continue" size="100"> +<script> +setup({explicit_timeout: true}); +async_test(t => { + document.oncut = t.step_func_done(event => { + // Nothing can be asserted about the event target until + // https://github.com/w3c/clipboard-apis/issues/70 is resolved. + // assert_equals(event.target, document.body, 'event.target'); + assert_true(event.isTrusted, 'event.isTrusted'); + assert_true(event.composed, 'event.composed'); + }); +}); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/events/paste-event-manual.html b/testing/web-platform/tests/clipboard-apis/events/paste-event-manual.html new file mode 100644 index 0000000000..608a0d6f23 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/events/paste-event-manual.html @@ -0,0 +1,21 @@ +<!doctype html> +<title>The paste event</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#clipboard-event-paste"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<input placeholder="Paste any text here to continue" size="100"> +<p>Some pre-selected text to copy for convenience</p> +<script> +setup({explicit_timeout: true}); +async_test(t => { + getSelection().selectAllChildren(document.querySelector('p')); + document.onpaste = t.step_func_done(event => { + // Nothing can be asserted about the event target until + // https://github.com/w3c/clipboard-apis/issues/70 is resolved. + // assert_equals(event.target, document.body, 'event.target'); + assert_true(event.isTrusted, 'event.isTrusted'); + assert_true(event.composed, 'event.composed'); + }); +}); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-disabled-by-feature-policy.tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-disabled-by-feature-policy.tentative.https.sub.html new file mode 100644 index 0000000000..7af2b8944e --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-disabled-by-feature-policy.tentative.https.sub.html @@ -0,0 +1,40 @@ +<!doctype html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-read.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +promise_test(async t => { + await test_driver.set_permission({ name: 'clipboard-read' }, 'granted'); + return promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.readText('test text')); +}, 'Feature-Policy header clipboard-read "none" disallows the top-level document.'); + +async_test(t => { + test_feature_availability( + 'navigator.clipboard.readText()', + t, + same_origin_src, + expect_feature_unavailable_default + ); +}, 'Feature-Policy header clipboard-read "none" disallows same-origin iframes.'); + +async_test(t => { + test_feature_availability( + 'navigator.clipboard.readText()', + t, + cross_origin_src, + expect_feature_unavailable_default + ); +}, 'Feature-Policy header clipboard-read "none" disallows cross-origin iframes.'); +</script> +</body> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-disabled-by-feature-policy.tentative.https.sub.html.headers b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-disabled-by-feature-policy.tentative.https.sub.html.headers new file mode 100644 index 0000000000..ee9a2b6fb6 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-disabled-by-feature-policy.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: clipboard-read 'none' diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html new file mode 100644 index 0000000000..367d033d0f --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html @@ -0,0 +1,31 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-read.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +// TODO(https://github.com/whatwg/html/issues/5493, https://crbug.com/1074482): +// In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome +// only, cross-origin focus is asynchronous. Implement WPT support for +// cross-origin focus. +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.readText()', + t, + cross_origin_src, + expect_feature_available_default, + 'clipboard-read' + ); +}, 'Feature policy "clipboard-read" can be enabled in cross-origin iframe using allow="clipboard-read" attribute'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html new file mode 100644 index 0000000000..e812854b4c --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html @@ -0,0 +1,25 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-read.html'; + +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.readText()', + t, + same_origin_src, + expect_feature_available_default, + 'clipboard-read' + ); +}, 'Feature policy "clipboard-read" can be enabled in same-origin iframe using allow="clipboard-read" attribute'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html new file mode 100644 index 0000000000..c371ea3b41 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html @@ -0,0 +1,30 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-read.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +// TODO(https://github.com/whatwg/html/issues/5493, https://crbug.com/1074482): +// In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome +// only, cross-origin focus is asynchronous. Implement WPT support for +// cross-origin focus. +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.readText()', + t, + cross_origin_src, + expect_feature_available_default + ); +}, 'Feature-Policy header clipboard-read "*" allows cross-origin iframes.'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin.tentative.https.sub.html.headers b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin.tentative.https.sub.html.headers new file mode 100644 index 0000000000..a147e2a64f --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: clipboard-read * diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html new file mode 100644 index 0000000000..552183cc67 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html @@ -0,0 +1,32 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-read.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +promise_test(async t => { + await test_driver.set_permission({ name: 'clipboard-read' }, 'granted'); + await waitForUserActivation(); + await navigator.clipboard.readText('test text'); +}, 'Feature-Policy header clipboard-read "*" allows the top-level document.'); + +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.readText()', + t, + same_origin_src, + expect_feature_available_default + ); +}, 'Feature-Policy header clipboard-read "*" allows same-origin iframes.'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html.headers b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html.headers new file mode 100644 index 0000000000..a147e2a64f --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: clipboard-read * diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html new file mode 100644 index 0000000000..17dc3628a7 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html @@ -0,0 +1,45 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-read.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +promise_test(async t => { + await test_driver.set_permission({ name: 'clipboard-read' }, 'granted'); + await waitForUserActivation(); + await navigator.clipboard.readText('test text'); +}, 'Feature-Policy header clipboard-read "self" allows the top-level document.'); + +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.readText()', + t, + same_origin_src, + expect_feature_available_default + ); +}, 'Feature-Policy header clipboard-read "self" allows same-origin iframes.'); + +// TODO(https://github.com/whatwg/html/issues/5493, https://crbug.com/1074482): +// In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome +// only, cross-origin focus is asynchronous. Implement WPT support for +// cross-origin focus. +promise_test(async t => { + test_feature_availability( + 'navigator.clipboard.readText()', + t, + cross_origin_src, + expect_feature_unavailable_default + ); +}, 'Feature-Policy header clipboard-read "self" disallows cross-origin iframes.'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html.headers b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html.headers new file mode 100644 index 0000000000..752d7faff4 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: clipboard-read 'self' diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-disabled-by-feature-policy.tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-disabled-by-feature-policy.tentative.https.sub.html new file mode 100644 index 0000000000..5d19d8dd6f --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-disabled-by-feature-policy.tentative.https.sub.html @@ -0,0 +1,40 @@ +<!doctype html> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-write.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +promise_test(async t => { + await test_driver.set_permission({ name: 'clipboard-write' }, 'granted'); + return promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.writeText('test text')); +}, 'Feature-Policy header clipboard-write "none" disallows the top-level document.'); + +async_test(t => { + test_feature_availability( + 'navigator.clipboard.writeText("test text")', + t, + same_origin_src, + expect_feature_unavailable_default + ); +}, 'Feature-Policy header clipboard-write "none" disallows same-origin iframes.'); + +async_test(t => { + test_feature_availability( + 'navigator.clipboard.writeText("test text")', + t, + cross_origin_src, + expect_feature_unavailable_default + ); +}, 'Feature-Policy header clipboard-write "none" disallows cross-origin iframes.'); +</script> +</body> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-disabled-by-feature-policy.tentative.https.sub.html.headers b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-disabled-by-feature-policy.tentative.https.sub.html.headers new file mode 100644 index 0000000000..f35f5b6a09 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-disabled-by-feature-policy.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: clipboard-write 'none' diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html new file mode 100644 index 0000000000..e669c8fec4 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html @@ -0,0 +1,31 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-write.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +// TODO(https://github.com/whatwg/html/issues/5493, https://crbug.com/1074482): +// In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome +// only, cross-origin focus is asynchronous. Implement WPT support for +// cross-origin focus. +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.writeText("test text")', + t, + cross_origin_src, + expect_feature_available_default, + 'clipboard-write' + ); +}, 'Feature policy "clipboard-write" can be enabled in cross-origin iframe using allow="clipboard-write" attribute'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html new file mode 100644 index 0000000000..b57dfe3dd2 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html @@ -0,0 +1,25 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-write.html'; + +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.writeText("test text")', + t, + same_origin_src, + expect_feature_available_default, + 'clipboard-write' + ); +}, 'Feature policy "clipboard-write" can be enabled in same-origin iframe using allow="clipboard-write" attribute'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html new file mode 100644 index 0000000000..6e7029cc78 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html @@ -0,0 +1,30 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-write.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +// TODO(https://github.com/whatwg/html/issues/5493, https://crbug.com/1074482): +// In Chrome and Firefox, Cross-origin focus requires user gesture. In Chrome +// only, cross-origin focus is asynchronous. Implement WPT support for +// cross-origin focus. +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.writeText("test text")', + t, + cross_origin_src, + expect_feature_available_default + ); +}, 'Feature-Policy header clipboard-write "*" allows cross-origin iframes.'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin.tentative.https.sub.html.headers b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin.tentative.https.sub.html.headers new file mode 100644 index 0000000000..81b10d8e33 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: clipboard-write * diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html new file mode 100644 index 0000000000..ca97994c61 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html @@ -0,0 +1,32 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-write.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +promise_test(async t => { + await test_driver.set_permission({ name: 'clipboard-write' }, 'granted'); + await waitForUserActivation(); + await navigator.clipboard.writeText('test text'); +}, 'Feature-Policy header clipboard-write "*" allows the top-level document.'); + +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.writeText("test text")', + t, + same_origin_src, + expect_feature_available_default + ); +}, 'Feature-Policy header clipboard-write "*" allows same-origin iframes.'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html.headers b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html.headers new file mode 100644 index 0000000000..81b10d8e33 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: clipboard-write * diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html new file mode 100644 index 0000000000..5615a68ac5 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html @@ -0,0 +1,41 @@ +<!doctype html> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/feature-policy/resources/featurepolicy.js"></script> +<script src="../../resources/user-activation.js"></script> +<script> +'use strict'; + +const same_origin_src = + '/feature-policy/resources/feature-policy-clipboard-write.html'; +const cross_origin_src = + 'https://{{domains[www]}}:{{ports[https][0]}}' + same_origin_src; + +promise_test(async t => { + await test_driver.set_permission({ name: 'clipboard-write' }, 'granted'); + await waitForUserActivation(); + await navigator.clipboard.writeText('test text'); +}, 'Feature-Policy header clipboard-write "self" allows the top-level document.'); + +promise_test(async t => { + await waitForUserActivation(); + test_feature_availability( + 'navigator.clipboard.writeText("test text")', + t, + same_origin_src, + expect_feature_available_default + ); +}, 'Feature-Policy header clipboard-write "self" allows same-origin iframes.'); + +promise_test(async t => { + test_feature_availability( + 'navigator.clipboard.writeText("test text")', + t, + cross_origin_src, + expect_feature_unavailable_default + ); +}, 'Feature-Policy header clipboard-write "self" disallows cross-origin iframes.'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html.headers b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html.headers new file mode 100644 index 0000000000..e226f41c6a --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html.headers @@ -0,0 +1 @@ +Feature-Policy: clipboard-write 'self' diff --git a/testing/web-platform/tests/clipboard-apis/idlharness.https.window.js b/testing/web-platform/tests/clipboard-apis/idlharness.https.window.js new file mode 100644 index 0000000000..c22ee24544 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/idlharness.https.window.js @@ -0,0 +1,17 @@ +// META: timeout=long +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +idl_test( + ['clipboard-apis'], + ['dom', 'html', 'permissions'], + idl_array => { + idl_array.add_objects({ + Navigator: ['navigator'], + Clipboard: ['navigator.clipboard'], + ClipboardEvent: ['new ClipboardEvent("x")'], + }); + } +); diff --git a/testing/web-platform/tests/clipboard-apis/permissions/readText-denied.https.html b/testing/web-platform/tests/clipboard-apis/permissions/readText-denied.https.html new file mode 100644 index 0000000000..010f4ba21b --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/permissions/readText-denied.https.html @@ -0,0 +1,20 @@ +<!doctype html> +<meta charset="utf-8"> +<title>navigator.clipboard.readText() fails when permission denied</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'denied'); + await waitForUserActivation(); + await promise_rejects_dom(t, + 'NotAllowedError', navigator.clipboard.readText()); +}, 'navigator.clipboard.readText() fails when permission denied'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/permissions/readText-granted.https.html b/testing/web-platform/tests/clipboard-apis/permissions/readText-granted.https.html new file mode 100644 index 0000000000..e912bd64a8 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/permissions/readText-granted.https.html @@ -0,0 +1,19 @@ +<!doctype html> +<meta charset="utf-8"> +<title>navigator.clipboard.readText() succeeds when permission granted</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async () => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await waitForUserActivation(); + await navigator.clipboard.readText(); +}, 'navigator.clipboard.readText() succeeds when permission granted'); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/clipboard-apis/permissions/writeText-denied.https.html b/testing/web-platform/tests/clipboard-apis/permissions/writeText-denied.https.html new file mode 100644 index 0000000000..5fbcab4117 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/permissions/writeText-denied.https.html @@ -0,0 +1,20 @@ +<!doctype html> +<meta charset="utf-8"> +<title>navigator.clipboard.writeText() fails when permission denied</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-write'}, 'denied'); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.writeText('xyz')); +}, 'navigator.clipboard.writeText() fails when permission denied'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/permissions/writeText-granted.https.html b/testing/web-platform/tests/clipboard-apis/permissions/writeText-granted.https.html new file mode 100644 index 0000000000..ff347b7add --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/permissions/writeText-granted.https.html @@ -0,0 +1,19 @@ +<!doctype html> +<meta charset="utf-8"> +<title>navigator.clipboard.writeText() succeeds when permission granted</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<script> +'use strict'; + +promise_test(async () => { + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + await waitForUserActivation(); + await navigator.clipboard.writeText('xyz'); +}, 'navigator.clipboard.writeText() succeeds when permission granted'); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/clipboard-apis/resources/copied-file.txt b/testing/web-platform/tests/clipboard-apis/resources/copied-file.txt new file mode 100644 index 0000000000..56a2838b7d --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/resources/copied-file.txt @@ -0,0 +1 @@ +copied-file-contents diff --git a/testing/web-platform/tests/clipboard-apis/resources/greenbox.png b/testing/web-platform/tests/clipboard-apis/resources/greenbox.png Binary files differnew file mode 100644 index 0000000000..6e555e3b19 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/resources/greenbox.png diff --git a/testing/web-platform/tests/clipboard-apis/resources/user-activation.js b/testing/web-platform/tests/clipboard-apis/resources/user-activation.js new file mode 100644 index 0000000000..ed294bb9cb --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/resources/user-activation.js @@ -0,0 +1,25 @@ +'use strict'; + +// In order to use this function, please import testdriver.js and +// testdriver-vendor.js, and include a <body> element. +async function waitForUserActivation() { + if (window.opener) { + throw new Error( + "waitForUserActivation() only works in the top-level frame"); + } + const loadedPromise = new Promise(resolve => { + if(document.readyState == 'complete') { + resolve(); + return; + } + window.addEventListener('load', resolve, {once: true}); + }); + await loadedPromise; + + const clickedPromise = new Promise(resolve => { + document.body.addEventListener('click', resolve, {once: true}); + }); + + test_driver.click(document.body); + await clickedPromise; +} diff --git a/testing/web-platform/tests/clipboard-apis/text-write-read/async-write-read.https.html b/testing/web-platform/tests/clipboard-apis/text-write-read/async-write-read.https.html new file mode 100644 index 0000000000..c46e5d4317 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/text-write-read/async-write-read.https.html @@ -0,0 +1,41 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write ([text/plain ClipboardItem]) -> + read ([text/plain ClipboardItem]) tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<script> +async function readWriteTest(textInput) { + promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const blobInput = new Blob([textInput], {type: 'text/plain'}); + const clipboardItemInput = new ClipboardItem({'text/plain': blobInput}); + + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItemInput]); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + assert_equals(clipboardItems.length, 1); + const clipboardItemOutput = clipboardItems[0]; + assert_true(clipboardItemOutput instanceof ClipboardItem); + assert_equals(clipboardItemOutput.types.length, 1); + const blobOutput = await clipboardItemOutput.getType('text/plain'); + assert_equals(blobOutput.type, 'text/plain'); + + const textOutput = await (new Response(blobOutput)).text(); + assert_equals(textOutput, textInput); + }, 'Verify write and read clipboard given text: ' + textInput); +} + +readWriteTest('Clipboard write ([text/plain ClipboardItem]) -> read ([text/plain ClipboardItem]) test'); +readWriteTest('non-Latin1 text encoding test データ'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/text-write-read/async-write-readText.https.html b/testing/web-platform/tests/clipboard-apis/text-write-read/async-write-readText.https.html new file mode 100644 index 0000000000..66969b1777 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/text-write-read/async-write-readText.https.html @@ -0,0 +1,33 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard write ([text/plain ClipboardItem]) -> readText tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<script> +async function readWriteTest(textInput) { + promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const blobInput = new Blob([textInput], {type: 'text/plain'}); + const clipboardItem = new ClipboardItem({'text/plain': blobInput}); + + await waitForUserActivation(); + await navigator.clipboard.write([clipboardItem]); + await waitForUserActivation(); + const textOutput = await navigator.clipboard.readText(); + + assert_equals(textOutput, textInput); + }, 'Verify write and read clipboard given text: ' + textInput); +} + +readWriteTest('Clipboard write ([text/plain ClipboardItem) -> read text test'); +readWriteTest('non-Latin1 text encoding test データ'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/text-write-read/async-writeText-read.https.html b/testing/web-platform/tests/clipboard-apis/text-write-read/async-writeText-read.https.html new file mode 100644 index 0000000000..ddf563269a --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/text-write-read/async-writeText-read.https.html @@ -0,0 +1,37 @@ +<!doctype html> +<meta charset="utf-8"> +<title> + Async Clipboard writeText -> read ([text/plain ClipboardItem]) tests +</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<script> +async function readWriteTest(textInput) { + promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + await waitForUserActivation(); + await navigator.clipboard.writeText(textInput); + await waitForUserActivation(); + const clipboardItems = await navigator.clipboard.read(); + assert_equals(clipboardItems.length, 1); + const clipboardItem = clipboardItems[0]; + assert_true(clipboardItem instanceof ClipboardItem); + assert_equals(clipboardItem.types.length, 1); + const blobOutput = await clipboardItem.getType('text/plain'); + assert_equals(blobOutput.type, 'text/plain'); + + const textOutput = await (new Response(blobOutput)).text(); + assert_equals(textOutput, textInput); + }, 'Verify write and read clipboard given text: ' + textInput); +} + +readWriteTest('Clipboard write text -> read ([text/plain ClipboardItem]) test'); +readWriteTest('non-Latin1 text encoding test データ'); +</script> diff --git a/testing/web-platform/tests/clipboard-apis/text-write-read/async-writeText-readText.https.html b/testing/web-platform/tests/clipboard-apis/text-write-read/async-writeText-readText.https.html new file mode 100644 index 0000000000..0defdf7a70 --- /dev/null +++ b/testing/web-platform/tests/clipboard-apis/text-write-read/async-writeText-readText.https.html @@ -0,0 +1,28 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Async Clipboard writeText -> readText tests</title> +<link rel="help" href="https://w3c.github.io/clipboard-apis/#async-clipboard-api"> +<body>Body needed for test_driver.click()</body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../resources/user-activation.js"></script> +<script> +async function readWriteTest(textInput) { + promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + await waitForUserActivation(); + await navigator.clipboard.writeText(textInput); + await waitForUserActivation(); + const textOutput = await navigator.clipboard.readText(); + + assert_equals(textOutput, textInput); + }, 'Verify write and read clipboard given text: ' + textInput); +} + +readWriteTest('Clipboard write text -> read text test'); +readWriteTest('non-Latin1 text encoding test データ'); +</script> |