Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* -*- 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
requestLongerTimeout(2);
const kBaseUrlForContent = getRootDirectory(gTestPath).replace(
);
const kContentFileName = "file_toplevel.html";
const kContentFileUrl = kBaseUrlForContent + kContentFileName;
const kIsMac = navigator.platform.indexOf("Mac") > -1;
async function waitForPasteContextMenu() {
await waitForPasteMenuPopupEvent("shown");
let pasteButton = document.getElementById(kPasteMenuItemId);
info("Wait for paste button enabled");
await BrowserTestUtils.waitForMutationCondition(
pasteButton,
{ attributeFilter: ["disabled"] },
() => !pasteButton.disabled,
"Wait for paste button enabled"
);
}
async function readText(aBrowser) {
return SpecialPowers.spawn(aBrowser, [], async () => {
content.document.notifyUserGestureActivation();
return content.eval(`navigator.clipboard.readText();`);
});
}
async function testPasteContextMenu(
aBrowser,
aClipboardText,
aShouldShow = true
) {
let pasteButtonIsShown;
if (aShouldShow) {
pasteButtonIsShown = waitForPasteContextMenu();
}
let readTextRequest = readText(aBrowser);
if (aShouldShow) {
await pasteButtonIsShown;
}
info("Click paste button, request should be resolved");
if (aShouldShow) {
await promiseClickPasteButton();
}
is(await readTextRequest, aClipboardText, "Request should be resolved");
}
async function installAndStartExtension(aContentScript) {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
content_scripts: [
{
js: ["content_script.js"],
},
],
},
files: {
"content_script.js": aContentScript,
},
});
await extension.startup();
return extension;
}
function testExtensionContentScript(aContentScript, aMessage) {
add_task(async function test_context_menu_suppression_ext() {
info(`${aMessage}`);
const extension = await installAndStartExtension(aContentScript);
await BrowserTestUtils.withNewTab(
kContentFileUrl,
async function (browser) {
const clipboardText = "X" + Math.random();
await SpecialPowers.spawn(browser, [clipboardText], async text => {
info(`Set clipboard text to ${text}`);
let div = content.document.createElement("div");
div.id = "container";
div.innerText = text;
content.document.documentElement.appendChild(div);
});
let writePromise = extension.awaitMessage("write-data-ready");
// trigger keyboard shortcut to copy.
await EventUtils.synthesizeAndWaitKey(
"c",
kIsMac ? { accelKey: true } : { ctrlKey: true }
);
// Wait a bit for clipboard write.
await writePromise;
info("Test read from same frame");
await testPasteContextMenu(browser, clipboardText, false);
info("Test read from same-origin subframe");
await testPasteContextMenu(
browser.browsingContext.children[0],
clipboardText,
false
);
info("Test read from cross-origin subframe");
await testPasteContextMenu(
browser.browsingContext.children[1],
clipboardText,
true
);
}
);
await extension.unload();
});
}
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [
["dom.events.asyncClipboard.readText", true],
["dom.events.asyncClipboard.clipboardItem", true],
["test.events.async.enabled", true],
// Avoid paste button delay enabling making test too long.
["security.dialog_enable_delay", 0],
],
});
});
testExtensionContentScript(() => {
document.addEventListener("copy", function (e) {
e.preventDefault();
let div = document.getElementById("container");
let text = div.innerText;
e.clipboardData.setData("text/plain", text);
browser.test.sendMessage("write-data-ready");
});
}, "Write data by DataTransfer API in extension");
testExtensionContentScript(() => {
document.addEventListener("copy", async function (e) {
e.preventDefault();
let div = document.getElementById("container");
let text = div.innerText;
await navigator.clipboard.writeText(text);
browser.test.sendMessage("write-data-ready");
});
}, "Write data by Async Clipboard API in extension");