added basic selenium test suite, move the config page to its own tab
This commit is contained in:
parent
fbdba9fca7
commit
7cd3aedca4
9 changed files with 2126 additions and 487 deletions
|
@ -36,7 +36,7 @@
|
|||
function (allHosts) {
|
||||
|
||||
if (rootObject.runtime.lastError && !allHosts) {
|
||||
rootObject.browserAction.disable();
|
||||
// rootObject.browserAction.disable();
|
||||
rootObject.browserAction.setBadgeText({text: "-"});
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</section>
|
||||
<script src="../lib/init.js"></script>
|
||||
<script src="../lib/defaults.js"></script>
|
||||
<script src="../data/standards.js"></script>
|
||||
<script src="../lib/standards.js"></script>
|
||||
<script src="../lib/storage.js"></script>
|
||||
<script src="js/lib/vue.js"></script>
|
||||
<script src="js/state.js"></script>
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
]
|
||||
},
|
||||
"options_ui": {
|
||||
"page": "config/index.html"
|
||||
"page": "config/index.html",
|
||||
"open_in_tab": true
|
||||
}
|
||||
}
|
||||
|
|
2300
package-lock.json
generated
2300
package-lock.json
generated
File diff suppressed because it is too large
Load diff
17
package.json
17
package.json
|
@ -4,10 +4,7 @@
|
|||
"description": "Tools to generate Web API managing browser extensions for Firefox and Chrome.",
|
||||
"author": "Peter Snyder <psnyde2@uic.edu> (https://www.cs.uic.edu/~psnyder/)",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"web-ext": "^2.2.2"
|
||||
},
|
||||
"dependencies": {},
|
||||
"homepage": "https://github.com/snyderp/web-api-manager",
|
||||
"bugs": {
|
||||
"url": "https://github.com/snyderp/web-api-manager/issues",
|
||||
|
@ -24,7 +21,15 @@
|
|||
],
|
||||
"contributors": [],
|
||||
"scripts": {
|
||||
"bundle": "web-ext -s add-on -a dist build --overwrite-dest",
|
||||
"firefox": "web-ext -s add-on run"
|
||||
"bundle": "gulp && web-ext -s add-on -a dist build --overwrite-dest",
|
||||
"firefox": "web-ext -s add-on run",
|
||||
"test": "rm dist/* && npm run bundle && ln -s `ls dist/` dist/webapi_manager.zip && node_modules/mocha/bin/mocha test/functional/*.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"geckodriver": "^1.9.0",
|
||||
"gulp": "^3.9.1",
|
||||
"mocha": "^4.0.1",
|
||||
"selenium-webdriver": "^3.6.0",
|
||||
"web-ext": "^2.2.2"
|
||||
}
|
||||
}
|
||||
|
|
89
test/functional/block.js
Normal file
89
test/functional/block.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
"use strict";
|
||||
|
||||
const assert = require("assert");
|
||||
const http = require("http");
|
||||
const utils = require("./lib/utils");
|
||||
const injected = require("./lib/injected");
|
||||
|
||||
describe("Basic", function () {
|
||||
|
||||
const testPort = 8989;
|
||||
const testUrl = `http://localhost:${testPort}`;
|
||||
const svgTestScript = injected.testSVGTestScript();
|
||||
|
||||
let httpServer;
|
||||
|
||||
this.timeout = function () {
|
||||
return 10000;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
httpServer = http.createServer(function (req, res) {
|
||||
const staticResponse = `<!DOCTYPE "html">
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Test Content</p>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
res.writeHead(200, {"Content-Type": "text/html"});
|
||||
res.write(staticResponse);
|
||||
res.end();
|
||||
});
|
||||
httpServer.listen(8989);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
httpServer.close();
|
||||
});
|
||||
|
||||
describe("Blocking", function () {
|
||||
|
||||
it("SVG Not Blocking", function (done) {
|
||||
const standardsToBlock = [];
|
||||
let driverReference;
|
||||
|
||||
utils.promiseGetDriver()
|
||||
.then(function (driver, addonId) {
|
||||
driverReference = driver;
|
||||
return utils.promiseSetBlockingRules(driver, standardsToBlock);
|
||||
})
|
||||
.then(function (result) {
|
||||
return driverReference.get(testUrl);
|
||||
})
|
||||
.then(function () {
|
||||
return driverReference.executeAsyncScript(svgTestScript);
|
||||
})
|
||||
.catch(function () {
|
||||
// Since we're not blocking the SVG API, then the sample
|
||||
// SVG code should throw an exception.
|
||||
driverReference.quit();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("SVG Blocking", function (done) {
|
||||
const standardsToBlock = ["Scalable Vector Graphics (SVG) 1.1 (Second Edition)"];
|
||||
let driverReference;
|
||||
|
||||
utils.promiseGetDriver()
|
||||
.then(function (driver, addonId) {
|
||||
driverReference = driver;
|
||||
return utils.promiseSetBlockingRules(driver, standardsToBlock);
|
||||
})
|
||||
.then(function (result) {
|
||||
return driverReference.get(testUrl);
|
||||
})
|
||||
.then(function () {
|
||||
return driverReference.executeAsyncScript(svgTestScript);
|
||||
})
|
||||
.then(function () {
|
||||
driverReference.quit();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
91
test/functional/lib/injected.js
Normal file
91
test/functional/lib/injected.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
// This module contains functions that *are not* executed as part of the
|
||||
// node process, but injected into the browser during tests (using
|
||||
// Function.prototype.toString).
|
||||
|
||||
"use strict";
|
||||
|
||||
// Returns the contents of the provided function definition source.
|
||||
//
|
||||
// Ex "function () { return 1; }" -> "return 1";
|
||||
const stripFuncFromSource = function (source) {
|
||||
|
||||
const parts = source.split("\n").filter(x => !!x.trim());
|
||||
parts.splice(0, 1);
|
||||
parts.splice(parts.length - 1, 1);
|
||||
const recreatedScript = parts.join("\n");
|
||||
return recreatedScript;
|
||||
};
|
||||
|
||||
module.exports.temporaryAddOnInstallScript = (function () {
|
||||
|
||||
const funcToInject = function () {
|
||||
|
||||
let fileUtils = Components.utils.import('resource://gre/modules/FileUtils.jsm');
|
||||
let FileUtils = fileUtils.FileUtils;
|
||||
let callback = arguments[arguments.length - 1];
|
||||
Components.utils.import('resource://gre/modules/AddonManager.jsm');
|
||||
|
||||
let listener = {
|
||||
onInstallEnded: function(install, addon) {
|
||||
callback([addon.id, 0]);
|
||||
},
|
||||
onInstallFailed: function(install) {
|
||||
callback([null, install.error]);
|
||||
},
|
||||
onInstalled: function(addon) {
|
||||
AddonManager.removeAddonListener(listener);
|
||||
callback([addon.id, 0]);
|
||||
}
|
||||
};
|
||||
|
||||
let file = new FileUtils.File(arguments[0]);
|
||||
|
||||
AddonManager.addAddonListener(listener);
|
||||
AddonManager.installTemporaryAddon(file).catch(error => {
|
||||
Components.utils.reportError(error);
|
||||
callback([null, error]);
|
||||
});
|
||||
};
|
||||
|
||||
const funcSource = stripFuncFromSource(funcToInject.toString());
|
||||
|
||||
return function () {
|
||||
return funcSource;
|
||||
};
|
||||
}());
|
||||
|
||||
module.exports.setStandardsAsBlockedScript = (function () {
|
||||
|
||||
const funcToInject = function () {
|
||||
const doc = window.document;
|
||||
const callback = arguments[arguments.length - 1];
|
||||
const standardsToBlockArray = "###REPLACE###";
|
||||
|
||||
standardsToBlockArray.forEach(function (aStandardName) {
|
||||
const input = doc.querySelector(`input[value='${aStandardName}']`);
|
||||
input.click();
|
||||
});
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
const funcSource = stripFuncFromSource(funcToInject.toString());
|
||||
|
||||
return function (standardsToBlock) {
|
||||
return funcSource.replace('"###REPLACE###"', JSON.stringify(standardsToBlock));
|
||||
};
|
||||
}());
|
||||
|
||||
module.exports.testSVGTestScript = (function () {
|
||||
|
||||
const funcToInject = function () {
|
||||
const callback = arguments[arguments.length - 1];
|
||||
callback(HTMLEmbedElement.prototype.getSVGDocument.art.bart.fart());
|
||||
};
|
||||
|
||||
const funcSource = stripFuncFromSource(funcToInject.toString());
|
||||
|
||||
return function (standardsToBlock) {
|
||||
return funcSource;
|
||||
};
|
||||
}());
|
79
test/functional/lib/utils.js
Normal file
79
test/functional/lib/utils.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
"use strict";
|
||||
|
||||
// The geckodriver package downloads and installs geckodriver for us.
|
||||
// We use it by requiring it.
|
||||
require("geckodriver");
|
||||
|
||||
const firefox = require("selenium-webdriver/firefox");
|
||||
const webdriver = require("selenium-webdriver");
|
||||
const FxRunnerUtils = require("fx-runner/lib/utils");
|
||||
const injectedScripts = require("./injected");
|
||||
const fs = require("fs");
|
||||
const By = webdriver.By;
|
||||
const Context = firefox.Context;
|
||||
const until = webdriver.until;
|
||||
const path = require("path");
|
||||
|
||||
module.exports.promiseAddonButton = function (driver) {
|
||||
driver.setContext(Context.CHROME);
|
||||
return driver.wait(until.elementLocated(
|
||||
By.css("[tooltiptext='WebAPI Manager']")
|
||||
), 2000);
|
||||
};
|
||||
|
||||
module.exports.promiseExtensionConfigPage = function (driver) {
|
||||
const extensionIdPattern = /url\("moz-extension:\/\/(.*?)\/images/;
|
||||
return this.promiseAddonButton(driver)
|
||||
.then(button => button.getAttribute("style"))
|
||||
.then(function (buttonStyle) {
|
||||
const match = extensionIdPattern.exec(buttonStyle);
|
||||
const extensionId = match[1];
|
||||
driver.setContext(Context.CONTENT);
|
||||
return driver.get(`moz-extension://${extensionId}/config/index.html`);
|
||||
})
|
||||
};
|
||||
|
||||
module.exports.promiseAddonConfigButton = function (driver) {
|
||||
driver.setContext(Context.CHROME);
|
||||
return driver.wait(until.elementLocated(
|
||||
By.id("config-page-link")
|
||||
), 2000);
|
||||
};
|
||||
|
||||
module.exports.promiseSetBlockingRules = function (driver, standardsToBlock) {
|
||||
const setStandardsScript = injectedScripts.setStandardsAsBlockedScript(standardsToBlock);
|
||||
driver.setContext(Context.CONTENT);
|
||||
|
||||
return this.promiseExtensionConfigPage(driver)
|
||||
.then(driver.executeAsyncScript(setStandardsScript));
|
||||
};
|
||||
|
||||
module.exports.promiseGetDriver = function (callback) {
|
||||
|
||||
let driver = new webdriver.Builder()
|
||||
.forBrowser('firefox')
|
||||
.build();
|
||||
|
||||
driver.setContext(Context.CHROME);
|
||||
|
||||
let fileLocation = path.join(process.cwd(), "dist", "webapi_manager.zip");
|
||||
|
||||
// This manually installs the add-on as a temporary add-on.
|
||||
// Hopefully selenium/geckodriver will get a way to do this soon:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1298025
|
||||
let installAddOnPromise = driver.executeAsyncScript(
|
||||
injectedScripts.temporaryAddOnInstallScript(),
|
||||
fileLocation
|
||||
);
|
||||
|
||||
return installAddOnPromise
|
||||
.then(function (result) {
|
||||
if (!result[0] && result[1]) {
|
||||
return driver.quit().then(() => {
|
||||
throw new Error(`Failed to install add-on: ${result[1]}`);
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve(driver, result[0]);
|
||||
});
|
||||
};
|
30
test/functional/logins.js
Normal file
30
test/functional/logins.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
|
||||
let assert = require("assert");
|
||||
let utils = require("./lib/utils");
|
||||
|
||||
describe("Test logging into popular sites", function () {
|
||||
|
||||
this.timeout = function () {
|
||||
return 10000;
|
||||
};
|
||||
|
||||
describe("GitHub", function () {
|
||||
|
||||
it("Log into site", function (done) {
|
||||
|
||||
const standardsToBlock = ["Beacon"];
|
||||
let driver;
|
||||
|
||||
utils.promiseGetDriver()
|
||||
.then(function (driver, addonId) {
|
||||
driver = driver;
|
||||
return utils.promiseSetBlockingRules(driver, standardsToBlock);
|
||||
});
|
||||
// .then(_ => utils.promiseAddonConfigButton(driver))
|
||||
// .then(function (configButton) {
|
||||
// configButton.click();
|
||||
// });
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue