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) {
|
function (allHosts) {
|
||||||
|
|
||||||
if (rootObject.runtime.lastError && !allHosts) {
|
if (rootObject.runtime.lastError && !allHosts) {
|
||||||
rootObject.browserAction.disable();
|
// rootObject.browserAction.disable();
|
||||||
rootObject.browserAction.setBadgeText({text: "-"});
|
rootObject.browserAction.setBadgeText({text: "-"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
</section>
|
</section>
|
||||||
<script src="../lib/init.js"></script>
|
<script src="../lib/init.js"></script>
|
||||||
<script src="../lib/defaults.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="../lib/storage.js"></script>
|
||||||
<script src="js/lib/vue.js"></script>
|
<script src="js/lib/vue.js"></script>
|
||||||
<script src="js/state.js"></script>
|
<script src="js/state.js"></script>
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"options_ui": {
|
"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.",
|
"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/)",
|
"author": "Peter Snyder <psnyde2@uic.edu> (https://www.cs.uic.edu/~psnyder/)",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {},
|
||||||
"gulp": "^3.9.1",
|
|
||||||
"web-ext": "^2.2.2"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/snyderp/web-api-manager",
|
"homepage": "https://github.com/snyderp/web-api-manager",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/snyderp/web-api-manager/issues",
|
"url": "https://github.com/snyderp/web-api-manager/issues",
|
||||||
|
@ -24,7 +21,15 @@
|
||||||
],
|
],
|
||||||
"contributors": [],
|
"contributors": [],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bundle": "web-ext -s add-on -a dist build --overwrite-dest",
|
"bundle": "gulp && web-ext -s add-on -a dist build --overwrite-dest",
|
||||||
"firefox": "web-ext -s add-on run"
|
"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…
Add table
Reference in a new issue