Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: headless OR a11y_checks
- Manifest: dom/events/test/clipboard/browser.toml
/* -*- Mode: JavaScript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
"use strict";
/* import-globals-from head.js */
const kContentFileUrl = kBaseUrlForContent + "simple_page_ext.html";
const sharedScript = function () {
this.clipboardRead = function () {
return navigator.clipboard
.read()
.then(items => {
browser.test.assertEq(1, items.length, "Should only 1 ClipboardItem");
const item = items[0];
browser.test.assertEq(
1,
item.types.length,
"ClipboardItem should contain only one type"
);
browser.test.assertEq(
"text/plain",
item.types[0],
"Type should be text/plain"
);
return item.getType("text/plain");
})
.then(blob => {
return blob.text();
})
.then(text => {
browser.test.sendMessage("result", text);
})
.catch(error => {
browser.test.sendMessage("result", [error.name, error.message]);
});
};
};
const contentScript = function () {
document.querySelector("button").addEventListener("click", function (e) {
clipboardRead();
});
browser.test.sendMessage("ready");
};
const backgroundScript = function () {
clipboardRead();
};
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["test.events.async.enabled", true]],
});
});
// There’s another test that checks calling read() without permission in
// toolkit/components/extensions/test/mochitest/test_ext_async_clipboard.html.
describe("test extension without clipboardRead permission", () => {
it("test content script", async function () {
const text = await promiseWritingRandomTextToClipboard();
const extensionData = {
manifest: {
content_scripts: [
{
js: ["sharedScript.js", "contentscript.js"],
},
],
},
files: {
"sharedScript.js": sharedScript,
"contentscript.js": contentScript,
},
};
const extension = ExtensionTestUtils.loadExtension(extensionData);
await extension.startup();
await BrowserTestUtils.withNewTab(kContentFileUrl, async browser => {
await extension.awaitMessage("ready");
// click on the content and wait for pasted button shown.
await Promise.all([
promisePasteButtonIsShown(),
promiseClickContentElement(browser, "btn"),
]);
// click on the paste button.
let resultPromise = extension.awaitMessage("result");
await Promise.all([
promisePasteButtonIsHidden(),
promiseClickPasteButton(),
]);
is(await resultPromise, text, "check read() result");
// click on the content and wait for pasted button shown.
await Promise.all([
promisePasteButtonIsShown(),
promiseClickContentElement(browser, "btn"),
]);
// dismiss the paste button.
resultPromise = extension.awaitMessage("result");
await Promise.all([
promisePasteButtonIsHidden(),
promiseDismissPasteButton(),
]);
const [name, message] = await resultPromise;
is(name, "NotAllowedError", "check read() error name");
is(
message,
"Clipboard read operation is not allowed.",
"check read() error message"
);
});
await extension.unload();
});
describe("test background script", () => {
// paste button should not be shown during the test.
const popupShownListener = function (e) {
const pastePopup = document.getElementById(kPasteMenuPopupId);
if (e.target != pastePopup) {
return;
}
ok(
false,
"Paste popup should not be shown for extension with permission"
);
promiseDismissPasteButton();
};
beforeEach(() => {
document.addEventListener("popupshown", popupShownListener);
});
afterEach(() => {
document.removeEventListener("popupshown", popupShownListener);
});
it("test without user activation", async function () {
const text = await promiseWritingRandomTextToClipboard();
const extensionData = {
background: [sharedScript, backgroundScript],
};
const extension = ExtensionTestUtils.loadExtension(extensionData);
await extension.startup();
const [name, message] = await extension.awaitMessage("result");
is(name, "NotAllowedError", "check read() error name");
is(
message,
"Clipboard read request was blocked due to lack of user activation.",
"check read() error message"
);
await extension.unload();
});
it("test with user activation", async function () {
const backgroundScriptWithUserActivation = function () {
browser.test.withHandlingUserInput(() => {
clipboardRead();
});
};
const text = await promiseWritingRandomTextToClipboard();
const extensionData = {
background: [sharedScript, backgroundScriptWithUserActivation],
};
const extension = ExtensionTestUtils.loadExtension(extensionData);
await extension.startup();
const [name, message] = await extension.awaitMessage("result");
is(name, "NotAllowedError", "check read() error name");
is(
message,
"Clipboard read operation is not allowed.",
"check read() error message"
);
await extension.unload();
});
});
});
// There’s another test that checks calling read() with permission in
// toolkit/components/extensions/test/mochitest/test_ext_async_clipboard.html.
describe("test extension with clipboardRead permission", () => {
// paste button should not be shown during the test.
const popupShownListener = function (e) {
const pastePopup = document.getElementById(kPasteMenuPopupId);
if (e.target != pastePopup) {
return;
}
ok(false, "Paste popup should not be shown for extension with permission");
promiseDismissPasteButton();
};
beforeEach(() => {
document.addEventListener("popupshown", popupShownListener);
});
afterEach(() => {
document.removeEventListener("popupshown", popupShownListener);
});
it("test content script", async function () {
const text = await promiseWritingRandomTextToClipboard();
const extensionData = {
manifest: {
content_scripts: [
{
js: ["sharedScript.js", "contentscript.js"],
},
],
permissions: ["clipboardRead"],
},
files: {
"sharedScript.js": sharedScript,
"contentscript.js": contentScript,
},
};
const extension = ExtensionTestUtils.loadExtension(extensionData);
await extension.startup();
await BrowserTestUtils.withNewTab(kContentFileUrl, async browser => {
await extension.awaitMessage("ready");
// extension with clipboardRead permission should not show paste button.
const resultPromise = extension.awaitMessage("result");
await promiseClickContentElement(browser, "btn");
is(await resultPromise, text, "check read() result");
});
await extension.unload();
});
it("test background script", async function () {
const text = await promiseWritingRandomTextToClipboard();
const extensionData = {
background: [sharedScript, backgroundScript],
manifest: {
permissions: ["clipboardRead"],
},
};
const extension = ExtensionTestUtils.loadExtension(extensionData);
await extension.startup();
is(await extension.awaitMessage("result"), text, "check read() result");
await extension.unload();
});
});