diff --git a/.eslintrc b/.eslintrc
index a149d14..13ed046 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,5 +1,8 @@
{
"root": true,
+
+ "parser": "babel-eslint",
+
"parserOptions": {
"ecmaVersion": 6,
},
@@ -429,7 +432,7 @@
"spaced-comment": [2, "always"],
// Require "use strict" to be defined globally in the script.
- "strict": [2, "global"],
+ "strict": [0, "global"],
// Allow vars to be declared anywhere in the scope.
"vars-on-top": 0,
diff --git a/.travis.yml b/.travis.yml
index af9f280..1992024 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,6 +11,10 @@ script:
- echo "RE-RUN tests on the webpack and browserify bundled files" &&
npm install -g browserify webpack &&
./test/run-module-bundlers-smoketests.sh
+- export DISPLAY=:99.0
+- sh -e /etc/init.d/xvfb start
+- echo "RUN integration tests on chrome" &&
+ ./test/run-chrome-smoketests.sh
after_script: npm run publish-coverage
diff --git a/package.json b/package.json
index 616e3c5..5db7228 100644
--- a/package.json
+++ b/package.json
@@ -17,10 +17,14 @@
},
"homepage": "https://github.com/mozilla/webextension-polyfill",
"devDependencies": {
+ "async-wait-until": "^1.1.5",
+ "babel-eslint": "^8.0.1",
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
- "babel-preset-babili": "0.0.10",
+ "babel-preset-babili": "^0.0.10",
+ "babel-preset-es2017": "^6.24.1",
"chai": "^3.5.0",
- "eslint": "3.9.1",
+ "eslint": "^3.9.1",
+ "finalhandler": "^1.1.0",
"grunt": "^1.0.1",
"grunt-babel": "^6.0.0",
"grunt-contrib-concat": "^1.0.1",
@@ -31,6 +35,8 @@
"jsdom": "^9.6.0",
"mocha": "^3.1.0",
"nyc": "^8.3.1",
+ "puppeteer": "^0.10.2",
+ "serve-static": "^1.13.1",
"sinon": "^1.17.6"
},
"nyc": {
@@ -47,6 +53,7 @@
"publish-coverage": "grunt coveralls",
"test": "mocha",
"test-coverage": "COVERAGE=y nyc mocha",
- "test-minified": "TEST_MINIFIED_POLYFILL=1 mocha"
+ "test-minified": "TEST_MINIFIED_POLYFILL=1 mocha",
+ "test-integration": "mocha -r test/mocha-babel test/integration/test-*"
}
}
diff --git a/test/fixtures/index.html b/test/fixtures/index.html
new file mode 100644
index 0000000..151a140
--- /dev/null
+++ b/test/fixtures/index.html
@@ -0,0 +1,10 @@
+
+
+
+ Browser Polyfill Test Page
+
+
+
+ Browser Polyfill Test Page
+
+
diff --git a/test/fixtures/runtime-messaging-extension/background.js b/test/fixtures/runtime-messaging-extension/background.js
new file mode 100644
index 0000000..db8d4d2
--- /dev/null
+++ b/test/fixtures/runtime-messaging-extension/background.js
@@ -0,0 +1,11 @@
+const {name} = browser.runtime.getManifest();
+
+console.log(name, "background page loaded");
+
+browser.runtime.onMessage.addListener((msg, sender) => {
+ console.log(name, "background received msg", {msg, sender});
+
+ return Promise.resolve("background page reply");
+});
+
+console.log(name, "background page ready to receive a content script message...");
diff --git a/test/fixtures/runtime-messaging-extension/content.js b/test/fixtures/runtime-messaging-extension/content.js
new file mode 100644
index 0000000..435d931
--- /dev/null
+++ b/test/fixtures/runtime-messaging-extension/content.js
@@ -0,0 +1,9 @@
+const {name} = browser.runtime.getManifest();
+
+console.log(name, "content script loaded");
+
+browser.runtime.sendMessage("content script message").then(reply => {
+ console.log(name, "content script received reply", {reply});
+});
+
+console.log(name, "content script message sent");
diff --git a/test/fixtures/runtime-messaging-extension/manifest.json b/test/fixtures/runtime-messaging-extension/manifest.json
new file mode 100644
index 0000000..084a423
--- /dev/null
+++ b/test/fixtures/runtime-messaging-extension/manifest.json
@@ -0,0 +1,24 @@
+{
+ "manifest_version": 2,
+ "name": "test-extension-runtime-messaging",
+ "version": "0.1",
+ "description": "test-extension-runtime-messaging",
+ "content_scripts": [
+ {
+ "matches": [
+ "http://localhost/*"
+ ],
+ "js": [
+ "browser-polyfill.js",
+ "content.js"
+ ]
+ }
+ ],
+ "permissions": [],
+ "background": {
+ "scripts": [
+ "browser-polyfill.js",
+ "background.js"
+ ]
+ }
+}
diff --git a/test/integration/setup.js b/test/integration/setup.js
new file mode 100644
index 0000000..a6de495
--- /dev/null
+++ b/test/integration/setup.js
@@ -0,0 +1,21 @@
+const finalhandler = require("finalhandler");
+const http = require("http");
+const serveStatic = require("serve-static");
+
+exports.createHTTPServer = async (path) => {
+ var serve = serveStatic(path);
+
+ var server = http.createServer((req, res) => {
+ serve(req, res, finalhandler(req, res));
+ });
+
+ return new Promise((resolve, reject) => {
+ server.listen((err) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(server);
+ }
+ });
+ });
+};
diff --git a/test/integration/test-runtime-messaging-on-chrome.js b/test/integration/test-runtime-messaging-on-chrome.js
new file mode 100644
index 0000000..a470de9
--- /dev/null
+++ b/test/integration/test-runtime-messaging-on-chrome.js
@@ -0,0 +1,92 @@
+"use strict";
+
+const path = require("path");
+
+const waitUntil = require("async-wait-until");
+const {deepEqual} = require("chai").assert;
+const puppeteer = require("puppeteer");
+
+const {createHTTPServer} = require("./setup");
+
+const fixtureExtensionDirName = "runtime-messaging-extension";
+
+const extensionName = require(`../fixtures/${fixtureExtensionDirName}/manifest.json`).name;
+
+describe("browser.runtime.onMessage/sendMessage", function() {
+ this.timeout(10000);
+
+ it("works as expected on Chrome", async () => {
+ const server = await createHTTPServer(path.join(__dirname, "..", "fixtures"));
+
+ const url = `http://localhost:${server.address().port}`;
+
+ const browser = await puppeteer.launch({
+ // Chrome Extensions are not currently supported in headless mode.
+ headless: false,
+
+ // Custom chrome arguments.
+ args: [
+ `--load-extension=${process.env.TEST_EXTENSIONS_PATH}/${fixtureExtensionDirName}`,
+ ],
+ });
+
+ const page = await browser.newPage();
+
+ const pageConsoleMessages = [];
+ const pageErrors = [];
+
+ page.on("console", (...args) => {
+ pageConsoleMessages.push(args);
+ });
+
+ page.on("error", (error) => {
+ pageErrors.push(error);
+ });
+
+ await page.goto(url);
+
+ const expectedConsoleMessages = [
+ [extensionName, "content script loaded"],
+ [extensionName, "content script message sent"],
+ [extensionName, "content script received reply", {"reply": "background page reply"}],
+ ];
+
+ const lastExpectedMessage = expectedConsoleMessages.slice(-1).pop();
+
+ let unexpectedException;
+
+ try {
+ // Wait until the last expected message has been received.
+ await waitUntil(() => {
+ return pageConsoleMessages.filter((msg) => {
+ return msg[0] === lastExpectedMessage[0] && msg[1] === lastExpectedMessage[1];
+ }).length > 0;
+ }, 5000);
+ } catch (error) {
+ // Collect any unexpected exception (e.g. a timeout error raised by waitUntil),
+ // it will be part of the deepEqual assertion of the results.
+ unexpectedException = error;
+ }
+
+ let actualResults = {
+ consoleMessages: pageConsoleMessages,
+ unexpectedException,
+ };
+
+ let expectedResults = {
+ consoleMessages: expectedConsoleMessages,
+ unexpectedException: undefined,
+ };
+
+ try {
+ deepEqual(actualResults, expectedResults, "Got the expected results");
+ } finally {
+ // ensure that we close the browser and the test HTTP server before exiting
+ // the test, even when the assertions fails.
+ await Promise.all([
+ browser.close(),
+ new Promise(resolve => server.close(resolve)),
+ ]);
+ }
+ });
+});
diff --git a/test/mocha-babel.js b/test/mocha-babel.js
new file mode 100644
index 0000000..a8c2969
--- /dev/null
+++ b/test/mocha-babel.js
@@ -0,0 +1,3 @@
+require("babel-core/register")({
+ presets: ["es2017"],
+});
diff --git a/test/run-chrome-smoketests.sh b/test/run-chrome-smoketests.sh
new file mode 100755
index 0000000..f91553e
--- /dev/null
+++ b/test/run-chrome-smoketests.sh
@@ -0,0 +1,21 @@
+echo "\nTest webextension-polyfill from an extension running on chrome"
+echo "==============================================="
+
+export TEST_EXTENSIONS_PATH=/tmp/browser-polyfill-chrome-smoketests
+
+MARKER_FILE=$TEST_EXTENSIONS_PATH/.created-for-run-chrome-smoketests
+
+# Check if the marker file exists and then remove the directory.
+if [ -f $MARKER_FILE ]; then
+ rm -fr $TEST_EXTENSIONS_PATH
+fi
+
+## Exits immediately if the directory already exists (which can only happen in a local
+## development environment, while this test will usually run on travis).
+mkdir $TEST_EXTENSIONS_PATH || exit 1
+touch $MARKER_FILE
+
+cp -rf test/fixtures/runtime-messaging-extension $TEST_EXTENSIONS_PATH
+cp -rf dist/browser-polyfill.js* $TEST_EXTENSIONS_PATH/runtime-messaging-extension/
+
+npm run test-integration