Bug 1298979 - Add test to verify that sending a message and unloading works r=billm

Checks what happens before closing a window or removing a frame:

- Tests that sendMessage/connect is received by the extension.
- Tests that any responses from the extension is not received by the
  sending script (of the closing context).

MozReview-Commit-ID: 9VwCpRmaZOO

--HG--
extra : rebase_source : f4103a10547835fec2a45086c39b3434937bcdce
This commit is contained in:
Rob Wu 2016-08-28 16:26:52 -07:00
Родитель 494ed12f50
Коммит 8456c63a68
2 изменённых файлов: 159 добавлений и 0 удалений

Просмотреть файл

@ -85,6 +85,7 @@ skip-if = os == 'android' # Android does not currently support tabs.
[test_ext_background_teardown.html]
[test_ext_tab_teardown.html]
skip-if = (os == 'android') # Android does not support tabs API. Bug 1260250
[test_ext_unload_frame.html]
[test_ext_i18n.html]
skip-if = (os == 'android') # Bug 1258975 on android.
[test_ext_web_accessible_resources.html]

Просмотреть файл

@ -0,0 +1,158 @@
<!DOCTYPE HTML>
<html>
<head>
<title>WebExtensions test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
</head>
<body>
<script>
"use strict";
/* globals delayedNotifyPass */ // Available in the background page of the test extensions.
// Background and content script for testSendMessage_*
function sendMessage_background() {
browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
browser.test.assertEq("from frame", msg, "Expected message from frame");
sendResponse("msg from back"); // Should not throw or anything like that.
delayedNotifyPass("Received sendMessage from closing frame");
});
}
function sendMessage_contentScript(testType) {
browser.runtime.sendMessage("from frame", reply => {
// The frame has been removed, so we should not get this callback!
browser.test.fail(`Unexpected reply: ${reply}`);
});
if (testType == "frame") {
frameElement.remove();
} else {
window.close();
}
}
// Background and content script for testConnect_*
function connect_background() {
browser.runtime.onConnect.addListener(port => {
browser.test.assertEq("port from frame", port.name);
let disconnected = false;
let hasMessage = false;
port.onDisconnect.addListener(() => {
browser.test.assertFalse(disconnected, "onDisconnect should fire once");
disconnected = true;
browser.test.assertTrue(hasMessage, "Expected onMessage before onDisconnect");
delayedNotifyPass("Received onDisconnect from closing frame");
});
port.onMessage.addListener(msg => {
browser.test.assertFalse(hasMessage, "onMessage should fire once");
hasMessage = true;
browser.test.assertFalse(disconnected, "Should get message before disconnect");
browser.test.assertEq("from frame", msg, "Expected message from frame");
});
port.postMessage("reply to closing frame");
});
}
function connect_contentScript(testType) {
let port = browser.runtime.connect({name: "port from frame"});
port.onMessage.addListener(msg => {
// The frame has been removed, so we should not get a reply.
browser.test.fail(`Unexpected reply: ${msg}`);
});
port.postMessage("from frame");
// Removing the frame or window should disconnect the port.
if (testType == "frame") {
frameElement.remove();
} else {
window.close();
}
}
// `testType` is "window" or "frame".
function createTestExtension(testType, backgroundScript, contentScript) {
// Make a roundtrip between the background page and the test runner (which is
// in the same process as the content script) to make sure that we record a
// failure in case the content script's sendMessage or onMessage handlers are
// called even after the frame or window was removed.
function delayedNotifyPass(msg) {
browser.test.onMessage.addListener((type, echoMsg) => {
if (type == "pong") {
browser.test.assertEq(msg, echoMsg, "Echoed reply should be the same");
browser.test.notifyPass(msg);
}
});
browser.test.log("Starting ping-pong to flush messages...");
browser.test.sendMessage("ping", msg);
}
let extension = ExtensionTestUtils.loadExtension({
background: `${delayedNotifyPass};(${backgroundScript})();`,
manifest: {
content_scripts: [{
js: ["contentscript.js"],
all_frames: testType == "frame",
matches: ["http://mochi.test/*/file_sample.html"],
}],
},
files: {
"contentscript.js": `(${contentScript})("${testType}");`,
},
});
extension.awaitMessage("ping").then(msg => {
extension.sendMessage("pong", msg);
});
return extension;
}
add_task(function* testSendMessage_and_remove_frame() {
let extension = createTestExtension("frame", sendMessage_background, sendMessage_contentScript);
yield extension.startup();
let frame = document.createElement("iframe");
frame.src = "file_sample.html";
document.body.appendChild(frame);
yield extension.awaitFinish("Received sendMessage from closing frame");
yield extension.unload();
});
add_task(function* testConnect_and_remove_frame() {
let extension = createTestExtension("frame", connect_background, connect_contentScript);
yield extension.startup();
let frame = document.createElement("iframe");
frame.src = "file_sample.html";
document.body.appendChild(frame);
yield extension.awaitFinish("Received onDisconnect from closing frame");
yield extension.unload();
});
add_task(function* testSendMessage_and_remove_window() {
let extension = createTestExtension("window", sendMessage_background, sendMessage_contentScript);
yield extension.startup();
window.open("file_sample.html");
yield extension.awaitFinish("Received sendMessage from closing frame");
yield extension.unload();
});
add_task(function* testConnect_and_remove_window() {
let extension = createTestExtension("window", connect_background, connect_contentScript);
yield extension.startup();
window.open("file_sample.html");
yield extension.awaitFinish("Received onDisconnect from closing frame");
yield extension.unload();
});
</script>
</body>
</html>