test(integration): Use node for running test scripts (#167)

* test(integration): Use node for running browser smoketests
* test(integration): Use node for running test scripts
This commit is contained in:
ExE Boss 2019-01-28 18:49:25 +01:00 committed by Luca Greco
parent 34a6ab4559
commit 83ec9e70ad
13 changed files with 105 additions and 61 deletions

View File

@ -10,6 +10,7 @@
"env": { "env": {
"browser": true, "browser": true,
"es6": true, "es6": true,
"node": true,
"webextensions": true, "webextensions": true,
}, },

View File

@ -10,11 +10,11 @@ script:
- echo "RE-RUN tests on the minified file" && npm run test-minified - echo "RE-RUN tests on the minified file" && npm run test-minified
- echo "RE-RUN tests on the webpack and browserify bundled files" && - echo "RE-RUN tests on the webpack and browserify bundled files" &&
npm install -g browserify webpack webpack-cli && npm install -g browserify webpack webpack-cli &&
./test/run-module-bundlers-smoketests.sh node ./scripts/run-module-bundlers-smoketests.js
- export DISPLAY=:99.0 - export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start - sh -e /etc/init.d/xvfb start
- echo "RUN integration tests on real browsers" && - echo "RUN integration tests on real browsers" &&
TRAVIS_CI=true ./test/run-browsers-smoketests.sh TRAVIS_CI=true node ./scripts/run-browsers-smoketests.js
## See https://docs.travis-ci.com/user/chrome ## See https://docs.travis-ci.com/user/chrome
sudo: required sudo: required

View File

@ -2,13 +2,11 @@
/* vim: set sts=2 sw=2 et tw=80: */ /* vim: set sts=2 sw=2 et tw=80: */
"use strict"; "use strict";
/* eslint-env commonjs */
const LICENSE = `/* This Source Code Form is subject to the terms of the Mozilla Public const LICENSE = `/* 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 * 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/. */`; * file, You can obtain one at http://mozilla.org/MPL/2.0/. */`;
const MINIFIED_FILE_FOOTER = `\n\n// <%= pkg.name %> v.<%= pkg.version %> (<%= pkg.homepage %>)\n\n${LICENSE}`; const MINIFIED_FILE_FOOTER = `\n// <%= pkg.name %> v.<%= pkg.version %> (<%= pkg.homepage %>)\n\n${LICENSE}\n`;
module.exports = function(grunt) { module.exports = function(grunt) {
grunt.initConfig({ grunt.initConfig({
@ -22,7 +20,7 @@ module.exports = function(grunt) {
eslint: { eslint: {
src: ["src/browser-polyfill.js", "Gruntfile.js"], src: ["src/browser-polyfill.js", "Gruntfile.js"],
test: ["test/**/*.js"], test: ["test/**/*.js", "scripts/**/*.js"],
}, },
replace: { replace: {

View File

@ -26,9 +26,10 @@
"browserify": "^16.2.2", "browserify": "^16.2.2",
"chai": "^3.5.0", "chai": "^3.5.0",
"chromedriver": "^2.38.3", "chromedriver": "^2.38.3",
"cross-env": "^5.2.0",
"eslint": "^3.9.1", "eslint": "^3.9.1",
"finalhandler": "^1.1.0", "finalhandler": "^1.1.0",
"geckodriver": "^1.11.0", "geckodriver": "^1.11.2",
"global-replaceify": "^1.0.0", "global-replaceify": "^1.0.0",
"grunt": "^1.0.1", "grunt": "^1.0.1",
"grunt-babel": "^6.0.0", "grunt-babel": "^6.0.0",
@ -62,8 +63,10 @@
"prepublish": "npm run build && npm run test", "prepublish": "npm run build && npm run test",
"publish-coverage": "grunt coveralls", "publish-coverage": "grunt coveralls",
"test": "mocha", "test": "mocha",
"test-coverage": "COVERAGE=y nyc mocha", "test-coverage": "cross-env COVERAGE=y nyc mocha",
"test-minified": "TEST_MINIFIED_POLYFILL=1 mocha", "test-minified": "cross-env TEST_MINIFIED_POLYFILL=1 mocha",
"test-integration": "tape test/integration/test-*" "test-integration": "tape test/integration/test-*",
"test-integration:chrome": "cross-env TEST_BROWSER_TYPE=chrome npm run test-integration | tap-nirvana",
"test-integration:firefox": "cross-env TEST_BROWSER_TYPE=firefox npm run test-integration | tap-nirvana"
} }
} }

View File

@ -0,0 +1,28 @@
#!/usr/bin/env node
"use strict";
const shell = require("shelljs");
/**
* This is to make sure that even if the tests fail on Chrome,
* the tests still run on Firefox, so that it can be seen whether
* Firefox broke too or is unaffected.
*/
let result = 0;
console.log(`
Test webextension-polyfill on real browsers
===========================================`);
// Enable headless mode (currently only used when running on Firefox
// because Chrome doesn't currently support the extensions in headless mode)
process.env.HEADLESS = 1;
console.log("\nRunning smoketests on Chrome");
process.env.TEST_BROWSER_TYPE = "chrome";
result = shell.exec("npm run test-integration:chrome").code || result;
console.log("\nRunning smoketests on Firefox");
process.env.TEST_BROWSER_TYPE = "firefox";
result = shell.exec("npm run test-integration:firefox").code || result;
process.exit(result);

View File

@ -0,0 +1,22 @@
#!/usr/bin/env node
const shell = require("shelljs");
let result = 0;
console.log(`
Test webextension-polyfill bundled with webpack
===============================================`);
process.env.TEST_BUNDLED_POLYFILL = "/tmp/webpack-bundle.js";
result = shell.exec(`webpack --mode production --entry ./test/fixtures/bundle-entrypoint.js --output ${process.env.TEST_BUNDLED_POLYFILL}`).code ||
shell.exec("npm run test").code || result;
console.log(`
Test webextension-polyfill bundled with browserify
==================================================`);
process.env.TEST_BUNDLED_POLYFILL = "/tmp/browserify-bundle.js";
result = shell.exec(`browserify test/fixtures/bundle-entrypoint.js > ${process.env.TEST_BUNDLED_POLYFILL}`).code ||
shell.exec("npm run test").code || result;
process.exit(result);

9
src/.eslintrc Normal file
View File

@ -0,0 +1,9 @@
{
"env": {
"node": false,
},
"globals": {
// Allow the `module` global, but not the `require(…)` function
"module": false,
},
}

View File

@ -509,7 +509,7 @@ if (typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.
// The build process adds a UMD wrapper around this file, which makes the // The build process adds a UMD wrapper around this file, which makes the
// `module` variable available. // `module` variable available.
module.exports = wrapAPIs(chrome); // eslint-disable-line no-undef module.exports = wrapAPIs(chrome);
} else { } else {
module.exports = browser; // eslint-disable-line no-undef module.exports = browser;
} }

View File

@ -1,11 +1,7 @@
{ {
"env": { "env": {
"mocha": true, "mocha": true,
"node": true,
"browser": true,
"webextensions": true
}, },
"globals": {},
"rules": { "rules": {
"max-nested-callbacks": ["warn", 6] "max-nested-callbacks": ["warn", 6]
} }

View File

@ -1,4 +1,4 @@
<!DOCTYPE> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Browser Polyfill Test Page</title> <title>Browser Polyfill Test Page</title>

View File

@ -16,7 +16,7 @@ const {cp} = require("shelljs");
const TEST_TIMEOUT = 5000; const TEST_TIMEOUT = 5000;
const launchBrowser = async (launchOptions) => { const launchBrowser = async (launchOptions) => {
const browser = launchOptions.browser || process.env.TEST_BROWSER_TYPE; const browser = launchOptions.browser;
const extensionPath = launchOptions.extensionPath; const extensionPath = launchOptions.extensionPath;
let driver; let driver;
@ -98,12 +98,12 @@ const createHTTPServer = async (path) => {
}); });
}; };
async function runExtensionTest(t, server, driver, extensionDirName) { async function runExtensionTest(t, server, driver, extensionDirName, browser) {
try { try {
const url = `http://localhost:${server.address().port}`; const url = `http://localhost:${server.address().port}`;
const userAgent = await driver.executeScript(() => window.navigator.userAgent); const userAgent = await driver.executeScript(() => window.navigator.userAgent);
t.pass(`Connected to browser: ${userAgent}"`); t.pass(`Connected to ${browser} browser: ${userAgent}"`);
await driver.get(url); await driver.get(url);
@ -138,16 +138,26 @@ const bundleTapeStandalone = async (destDir) => {
const stream = b.bundle(); const stream = b.bundle();
const onceStreamEnd = awaitStreamEnd(stream); const onceStreamEnd = awaitStreamEnd(stream);
stream.pipe(fs.createWriteStream(bundleFileName)); const destFileStream = fs.createWriteStream(bundleFileName);
const onceWritten = new Promise(resolve => {
destFileStream.on("close", resolve);
});
stream.pipe(destFileStream);
await onceStreamEnd; await Promise.all([onceStreamEnd, onceWritten]);
}; };
test.onFailure(() => { test.onFailure(() => {
process.exit(1); process.exit(1);
}); });
const defineExtensionTests = ({description, extensions}) => { /**
* @param {object} parameters
* @param {string} parameters.description
* @param {string[]} parameters.extensions
* @param {boolean|string|string[]} [parameters.skip]
*/
const defineExtensionTests = ({description, extensions, skip}) => {
for (const extensionDirName of extensions) { for (const extensionDirName of extensions) {
test(`${description} (test extension: ${extensionDirName})`, async (tt) => { test(`${description} (test extension: ${extensionDirName})`, async (tt) => {
let timeout; let timeout;
@ -155,6 +165,19 @@ const defineExtensionTests = ({description, extensions}) => {
let server; let server;
let tempDir; let tempDir;
const browser = process.env.TEST_BROWSER_TYPE;
if (skip) {
if (skip === true) {
tt.skip("Test extension skipped");
return;
} else if (skip instanceof Array ? skip.includes(browser) : skip === browser) {
tt.skip("Test extension skipped on: " + browser);
return;
}
console.log(`Skip condition ignored: '${skip}' != '${browser}'`);
}
try { try {
const srcExtensionPath = path.resolve( const srcExtensionPath = path.resolve(
path.join(__dirname, "..", "fixtures", extensionDirName)); path.join(__dirname, "..", "fixtures", extensionDirName));
@ -169,9 +192,9 @@ const defineExtensionTests = ({description, extensions}) => {
await bundleTapeStandalone(extensionPath); await bundleTapeStandalone(extensionPath);
server = await createHTTPServer(path.join(__dirname, "..", "fixtures")); server = await createHTTPServer(path.join(__dirname, "..", "fixtures"));
driver = await launchBrowser({extensionPath}); driver = await launchBrowser({extensionPath, browser});
await Promise.race([ await Promise.race([
runExtensionTest(tt, server, driver, extensionDirName), runExtensionTest(tt, server, driver, extensionDirName, browser),
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
timeout = setTimeout(() => reject(new Error(`test timeout after ${TEST_TIMEOUT}`)), TEST_TIMEOUT); timeout = setTimeout(() => reject(new Error(`test timeout after ${TEST_TIMEOUT}`)), TEST_TIMEOUT);
}), }),

View File

@ -1,20 +0,0 @@
#!/bin/bash
set -eo pipefail
echo ""
echo "Test webextension-polyfill on real browsers"
echo "==========================================="
export PATH=$PATH:./node_modules/.bin/
## HEADLESS=1 Enable the headless mode (currently used only on Firefox
## because Chrome doesn't currently support the extensions in headless mode)
export HEADLESS=1
echo ""
echo "Run smoketests on Chrome"
TEST_BROWSER_TYPE=chrome npm run test-integration | tap-nirvana
echo ""
echo "Run smoketests on Firefox"
TEST_BROWSER_TYPE=firefox npm run test-integration | tap-nirvana

View File

@ -1,16 +0,0 @@
#!/bin/bash
set -eo pipefail
echo ""
echo "Test webextension-polyfill bundled with webpack"
echo "==============================================="
webpack --mode production --entry ./test/fixtures/bundle-entrypoint.js --output /tmp/webpack-bundle.js
TEST_BUNDLED_POLYFILL=/tmp/webpack-bundle.js npm run test
echo ""
echo "Test webextension-polyfill bundled with browserify"
echo "=================================================="
browserify test/fixtures/bundle-entrypoint.js > /tmp/browserify-bundle.js
TEST_BUNDLED_POLYFILL=/tmp/browserify-bundle.js npm run test