Results of npm run format
This commit is contained in:
Родитель
445c8266a1
Коммит
16d823e68e
26
.eslintrc.js
26
.eslintrc.js
|
@ -7,18 +7,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"parserOptions": {
|
parserOptions: {
|
||||||
"ecmaVersion": 8,
|
ecmaVersion: 8,
|
||||||
"sourceType": "module",
|
sourceType: "module",
|
||||||
"ecmaFeatures": {
|
ecmaFeatures: {
|
||||||
"jsx": false,
|
jsx: false,
|
||||||
"experimentalObjectRestSpread": true,
|
experimentalObjectRestSpread: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
"es6": true,
|
es6: true,
|
||||||
// 'browser-window': false
|
// 'browser-window': false
|
||||||
|
|
||||||
},
|
},
|
||||||
extends: [
|
extends: [
|
||||||
"eslint:recommended",
|
"eslint:recommended",
|
||||||
|
@ -28,16 +27,13 @@ module.exports = {
|
||||||
"plugin:mozilla/recommended",
|
"plugin:mozilla/recommended",
|
||||||
],
|
],
|
||||||
|
|
||||||
plugins: [
|
plugins: ["json", "mozilla"],
|
||||||
"json",
|
|
||||||
"mozilla",
|
|
||||||
],
|
|
||||||
|
|
||||||
rules: {
|
rules: {
|
||||||
"babel/new-cap": "off",
|
"babel/new-cap": "off",
|
||||||
"comma-dangle": ["error", "always-multiline"],
|
"comma-dangle": ["error", "always-multiline"],
|
||||||
"eqeqeq": "error",
|
eqeqeq: "error",
|
||||||
"indent": ["warn", 2, { SwitchCase: 1 }],
|
indent: ["warn", 2, { SwitchCase: 1 }],
|
||||||
"mozilla/no-aArgs": "warn",
|
"mozilla/no-aArgs": "warn",
|
||||||
"mozilla/balanced-listeners": 0,
|
"mozilla/balanced-listeners": 0,
|
||||||
"no-console": "warn",
|
"no-console": "warn",
|
||||||
|
@ -45,6 +41,6 @@ module.exports = {
|
||||||
"no-unused-vars": "error",
|
"no-unused-vars": "error",
|
||||||
"prefer-const": "warn",
|
"prefer-const": "warn",
|
||||||
"prefer-spread": "error",
|
"prefer-spread": "error",
|
||||||
"semi": ["error", "always"],
|
semi: ["error", "always"],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,17 +5,29 @@
|
||||||
|
|
||||||
const { utils: Cu } = Components;
|
const { utils: Cu } = Components;
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
XPCOMUtils.defineLazyModuleGetter(
|
||||||
"resource://gre/modules/Services.jsm");
|
this,
|
||||||
|
"Services",
|
||||||
|
"resource://gre/modules/Services.jsm",
|
||||||
|
);
|
||||||
|
|
||||||
const STUDY = "button-icon-preference";
|
const STUDY = "button-icon-preference";
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "config",
|
XPCOMUtils.defineLazyModuleGetter(
|
||||||
`resource://${STUDY}/Config.jsm`);
|
this,
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "studyUtils",
|
"config",
|
||||||
`resource://${STUDY}/StudyUtils.jsm`);
|
`resource://${STUDY}/Config.jsm`,
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Feature",
|
);
|
||||||
`resource://${STUDY}/lib/Feature.jsm`);
|
XPCOMUtils.defineLazyModuleGetter(
|
||||||
|
this,
|
||||||
|
"studyUtils",
|
||||||
|
`resource://${STUDY}/StudyUtils.jsm`,
|
||||||
|
);
|
||||||
|
XPCOMUtils.defineLazyModuleGetter(
|
||||||
|
this,
|
||||||
|
"Feature",
|
||||||
|
`resource://${STUDY}/lib/Feature.jsm`,
|
||||||
|
);
|
||||||
|
|
||||||
/* Example addon-specific module imports. Remember to Unload during shutdown() below.
|
/* Example addon-specific module imports. Remember to Unload during shutdown() below.
|
||||||
|
|
||||||
|
@ -32,7 +44,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Feature",
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.Bootstrap = {
|
this.Bootstrap = {
|
||||||
|
|
||||||
VARIATION_OVERRIDE_PREF: "extensions.button_icon_preference.variation",
|
VARIATION_OVERRIDE_PREF: "extensions.button_icon_preference.variation",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +52,6 @@ this.Bootstrap = {
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async startup(addonData, reason) {
|
async startup(addonData, reason) {
|
||||||
|
|
||||||
this.REASONS = studyUtils.REASONS;
|
this.REASONS = studyUtils.REASONS;
|
||||||
|
|
||||||
this.initLog();
|
this.initLog();
|
||||||
|
@ -58,7 +68,10 @@ this.Bootstrap = {
|
||||||
// Check if the user is eligible to run this study using the |isEligible|
|
// Check if the user is eligible to run this study using the |isEligible|
|
||||||
// function when the study is initialized (install or upgrade, the latter
|
// function when the study is initialized (install or upgrade, the latter
|
||||||
// being interpreted as a new install).
|
// being interpreted as a new install).
|
||||||
if (reason === this.REASONS.ADDON_INSTALL || reason === this.REASONS.ADDON_UPGRADE) {
|
if (
|
||||||
|
reason === this.REASONS.ADDON_INSTALL ||
|
||||||
|
reason === this.REASONS.ADDON_UPGRADE
|
||||||
|
) {
|
||||||
// telemetry "enter" ONCE
|
// telemetry "enter" ONCE
|
||||||
studyUtils.firstSeen();
|
studyUtils.firstSeen();
|
||||||
const eligible = await config.isEligible();
|
const eligible = await config.isEligible();
|
||||||
|
@ -82,7 +95,12 @@ this.Bootstrap = {
|
||||||
this.log.debug(`info ${JSON.stringify(studyUtils.info())}`);
|
this.log.debug(`info ${JSON.stringify(studyUtils.info())}`);
|
||||||
|
|
||||||
// initiate the chrome-privileged part of the study add-on
|
// initiate the chrome-privileged part of the study add-on
|
||||||
this.feature = new Feature(variation, studyUtils, this.REASONS[reason], this.log);
|
this.feature = new Feature(
|
||||||
|
variation,
|
||||||
|
studyUtils,
|
||||||
|
this.REASONS[reason],
|
||||||
|
this.log,
|
||||||
|
);
|
||||||
|
|
||||||
// if you have code to handle expiration / long-timers, it could go here
|
// if you have code to handle expiration / long-timers, it could go here
|
||||||
/*
|
/*
|
||||||
|
@ -101,14 +119,15 @@ this.Bootstrap = {
|
||||||
/** spec for messages intended for Shield =>
|
/** spec for messages intended for Shield =>
|
||||||
* {shield:true,msg=[info|endStudy|telemetry],data=data}
|
* {shield:true,msg=[info|endStudy|telemetry],data=data}
|
||||||
*/
|
*/
|
||||||
browser.runtime.onMessage.addListener(studyUtils.respondToWebExtensionMessage);
|
browser.runtime.onMessage.addListener(
|
||||||
|
studyUtils.respondToWebExtensionMessage,
|
||||||
|
);
|
||||||
// other browser.runtime.onMessage handlers for your addon, if any
|
// other browser.runtime.onMessage handlers for your addon, if any
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// start up the chrome-privileged part of the study
|
// start up the chrome-privileged part of the study
|
||||||
this.feature.start();
|
this.feature.start();
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -117,8 +136,8 @@ this.Bootstrap = {
|
||||||
*/
|
*/
|
||||||
initLog() {
|
initLog() {
|
||||||
XPCOMUtils.defineLazyGetter(this, "log", () => {
|
XPCOMUtils.defineLazyGetter(this, "log", () => {
|
||||||
const ConsoleAPI =
|
const ConsoleAPI = Cu.import("resource://gre/modules/Console.jsm", {})
|
||||||
Cu.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
|
.ConsoleAPI;
|
||||||
const consoleOptions = {
|
const consoleOptions = {
|
||||||
maxLogLevel: config.log.bootstrap.level,
|
maxLogLevel: config.log.bootstrap.level,
|
||||||
prefix: "TPStudy",
|
prefix: "TPStudy",
|
||||||
|
@ -136,8 +155,9 @@ this.Bootstrap = {
|
||||||
|
|
||||||
// choose the variation for this particular user, then set it.
|
// choose the variation for this particular user, then set it.
|
||||||
async selectVariation() {
|
async selectVariation() {
|
||||||
const variation = this.getVariationFromPref(config.weightedVariations) ||
|
const variation =
|
||||||
await studyUtils.deterministicVariation(config.weightedVariations);
|
this.getVariationFromPref(config.weightedVariations) ||
|
||||||
|
(await studyUtils.deterministicVariation(config.weightedVariations));
|
||||||
studyUtils.setVariation(variation);
|
studyUtils.setVariation(variation);
|
||||||
this.log.debug(`studyUtils has config and variation.name: ${variation.name}.
|
this.log.debug(`studyUtils has config and variation.name: ${variation.name}.
|
||||||
Ready to send telemetry`);
|
Ready to send telemetry`);
|
||||||
|
@ -150,7 +170,9 @@ this.Bootstrap = {
|
||||||
if (name !== "") {
|
if (name !== "") {
|
||||||
const variation = weightedVariations.filter(x => x.name === name)[0];
|
const variation = weightedVariations.filter(x => x.name === name)[0];
|
||||||
if (!variation) {
|
if (!variation) {
|
||||||
throw new Error(`about:config => ${this.VARIATION_OVERRIDE_PREF} set to ${name},
|
throw new Error(`about:config => ${
|
||||||
|
this.VARIATION_OVERRIDE_PREF
|
||||||
|
} set to ${name},
|
||||||
but no variation with that name exists.`);
|
but no variation with that name exists.`);
|
||||||
}
|
}
|
||||||
return variation;
|
return variation;
|
||||||
|
@ -167,8 +189,9 @@ this.Bootstrap = {
|
||||||
async shutdown(addonData, reason) {
|
async shutdown(addonData, reason) {
|
||||||
this.log.debug("shutdown", this.REASONS[reason] || reason);
|
this.log.debug("shutdown", this.REASONS[reason] || reason);
|
||||||
|
|
||||||
const isUninstall = (reason === this.REASONS.ADDON_UNINSTALL
|
const isUninstall =
|
||||||
|| reason === this.REASONS.ADDON_DISABLE);
|
reason === this.REASONS.ADDON_UNINSTALL ||
|
||||||
|
reason === this.REASONS.ADDON_DISABLE;
|
||||||
if (isUninstall) {
|
if (isUninstall) {
|
||||||
this.log.debug("uninstall or disable");
|
this.log.debug("uninstall or disable");
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ class Feature {
|
||||||
});
|
});
|
||||||
feature.studyUtils.endStudy("introduction-leave-study");
|
feature.studyUtils.endStudy("introduction-leave-study");
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
// callback for nb events
|
// callback for nb events
|
||||||
null
|
null
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
{
|
{
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"webextensions": true
|
"webextensions": true
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": ["eslint:recommended"],
|
||||||
"eslint:recommended"
|
"rules": {
|
||||||
],
|
"no-console": "warn"
|
||||||
"rules": {
|
}
|
||||||
"no-console": "warn"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
* - Only the webExtension can initiate messages. see `msgStudyUtils("info")` below.
|
* - Only the webExtension can initiate messages. see `msgStudyUtils("info")` below.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** Re-usable code for talking to `studyUtils` using `browser.runtime.sendMessage`
|
/** Re-usable code for talking to `studyUtils` using `browser.runtime.sendMessage`
|
||||||
* - Host listens and responds at `bootstrap.js`:
|
* - Host listens and responds at `bootstrap.js`:
|
||||||
*
|
*
|
||||||
|
@ -27,7 +26,8 @@
|
||||||
*/
|
*/
|
||||||
async function msgStudyUtils(msg, data) {
|
async function msgStudyUtils(msg, data) {
|
||||||
const allowed = ["endStudy", "telemetry", "info"];
|
const allowed = ["endStudy", "telemetry", "info"];
|
||||||
if (!allowed.includes(msg)) throw new Error(`shieldUtils doesn't know ${msg}, only knows ${allowed}`);
|
if (!allowed.includes(msg))
|
||||||
|
throw new Error(`shieldUtils doesn't know ${msg}, only knows ${allowed}`);
|
||||||
try {
|
try {
|
||||||
// the "shield" key is how the Host listener knows it's for shield.
|
// the "shield" key is how the Host listener knows it's for shield.
|
||||||
return await browser.runtime.sendMessage({ shield: true, msg, data });
|
return await browser.runtime.sendMessage({ shield: true, msg, data });
|
||||||
|
@ -56,28 +56,31 @@ function telemetry(data) {
|
||||||
function throwIfInvalid(obj) {
|
function throwIfInvalid(obj) {
|
||||||
// Check: all keys and values must be strings,
|
// Check: all keys and values must be strings,
|
||||||
for (const k in obj) {
|
for (const k in obj) {
|
||||||
if (typeof k !== 'string') throw new Error(`key ${k} not a string`);
|
if (typeof k !== "string") throw new Error(`key ${k} not a string`);
|
||||||
if (typeof obj[k] !== 'string') throw new Error(`value ${k} ${obj[k]} not a string`);
|
if (typeof obj[k] !== "string")
|
||||||
|
throw new Error(`value ${k} ${obj[k]} not a string`);
|
||||||
}
|
}
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
throwIfInvalid(data);
|
throwIfInvalid(data);
|
||||||
return msgStudyUtils("telemetry", data);
|
return msgStudyUtils("telemetry", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class BrowserActionButtonChoiceFeature {
|
class BrowserActionButtonChoiceFeature {
|
||||||
/**
|
/**
|
||||||
* - set image, text, click handler (telemetry)
|
* - set image, text, click handler (telemetry)
|
||||||
* - tell Legacy Addon to send
|
* - tell Legacy Addon to send
|
||||||
*/
|
*/
|
||||||
constructor(variation) {
|
constructor(variation) {
|
||||||
console.log("initilizing BrowserActionButtonChoiceFeature:", variation.name);
|
console.log(
|
||||||
|
"initilizing BrowserActionButtonChoiceFeature:",
|
||||||
|
variation.name,
|
||||||
|
);
|
||||||
this.timesClickedInSession = 0;
|
this.timesClickedInSession = 0;
|
||||||
|
|
||||||
// modify BrowserAction (button) ui for this particular {variation}
|
// modify BrowserAction (button) ui for this particular {variation}
|
||||||
console.log("path:", `icons/${variation.name}.svg`)
|
console.log("path:", `icons/${variation.name}.svg`);
|
||||||
browser.browserAction.setIcon({ path: `icons/${variation.name}.svg` });
|
browser.browserAction.setIcon({ path: `icons/${variation.name}.svg` });
|
||||||
browser.browserAction.setTitle({ title: variation.name });
|
browser.browserAction.setTitle({ title: variation.name });
|
||||||
browser.browserAction.onClicked.addListener(() => this.handleButtonClick());
|
browser.browserAction.onClicked.addListener(() => this.handleButtonClick());
|
||||||
|
@ -92,15 +95,20 @@ class BrowserActionButtonChoiceFeature {
|
||||||
// note: doesn't persist across a session, unless you use localStorage or similar.
|
// note: doesn't persist across a session, unless you use localStorage or similar.
|
||||||
this.timesClickedInSession += 1;
|
this.timesClickedInSession += 1;
|
||||||
console.log("got a click", this.timesClickedInSession);
|
console.log("got a click", this.timesClickedInSession);
|
||||||
browser.browserAction.setBadgeText({ text: this.timesClickedInSession.toString() });
|
browser.browserAction.setBadgeText({
|
||||||
|
text: this.timesClickedInSession.toString(),
|
||||||
|
});
|
||||||
|
|
||||||
// telemetry: FIRST CLICK
|
// telemetry: FIRST CLICK
|
||||||
if (this.timesClickedInSession == 1) {
|
if (this.timesClickedInSession == 1) {
|
||||||
telemetry({ "event": "button-first-click-in-session" });
|
telemetry({ event: "button-first-click-in-session" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// telemetry EVERY CLICK
|
// telemetry EVERY CLICK
|
||||||
telemetry({ "event": "button-click", timesClickedInSession: "" + this.timesClickedInSession });
|
telemetry({
|
||||||
|
event: "button-click",
|
||||||
|
timesClickedInSession: "" + this.timesClickedInSession,
|
||||||
|
});
|
||||||
|
|
||||||
// webExtension-initiated ending for "used-often"
|
// webExtension-initiated ending for "used-often"
|
||||||
//
|
//
|
||||||
|
@ -119,13 +127,15 @@ class BrowserActionButtonChoiceFeature {
|
||||||
* 3. initialize the feature, using our specific variation
|
* 3. initialize the feature, using our specific variation
|
||||||
*/
|
*/
|
||||||
function runOnce() {
|
function runOnce() {
|
||||||
msgStudyUtils("info").then(
|
msgStudyUtils("info")
|
||||||
({ variation }) => new BrowserActionButtonChoiceFeature(variation)
|
.then(({ variation }) => new BrowserActionButtonChoiceFeature(variation))
|
||||||
).catch(function defaultSetup() {
|
.catch(function defaultSetup() {
|
||||||
// Errors here imply that this is NOT embedded.
|
// Errors here imply that this is NOT embedded.
|
||||||
console.log("you must be running as part of `web-ext`. You get 'corn dog'!");
|
console.log(
|
||||||
new BrowserActionButtonChoiceFeature({ "name": "isolatedcorndog" })
|
"you must be running as part of `web-ext`. You get 'corn dog'!",
|
||||||
});
|
);
|
||||||
|
new BrowserActionButtonChoiceFeature({ name: "isolatedcorndog" });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually start
|
// actually start
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
"eslint": "eslint . --ext jsm --ext js --ext json",
|
"eslint": "eslint . --ext jsm --ext js --ext json",
|
||||||
"eslint-fix": "eslint . --ext jsm --ext js --ext json --fix",
|
"eslint-fix": "eslint . --ext jsm --ext js --ext json --fix",
|
||||||
"firefox": "export XPI=dist/linked-addon.xpi && npm run build && node run-firefox.js",
|
"firefox": "export XPI=dist/linked-addon.xpi && npm run build && node run-firefox.js",
|
||||||
"format": "prettier '**/*.{css,js,json}' --trailing-comma=all --ignore-path=.eslintignore --print-width 160 --write",
|
"format": "prettier '**/*.{css,js,json}' --trailing-comma=all --ignore-path=.eslintignore --write && npm run eslint-fix",
|
||||||
"harness_test": "export XPI=dist/linked-addon.xpi && mocha test/functional_tests.js --retry 2 --reporter json",
|
"harness_test": "export XPI=dist/linked-addon.xpi && mocha test/functional_tests.js --retry 2 --reporter json",
|
||||||
"lint": "npm-run-all lint:*",
|
"lint": "npm-run-all lint:*",
|
||||||
"lint-build:addons-linter": "# actually a post build test: bin/addonLintTest ' + require('./package.json').name",
|
"lint-build:addons-linter": "# actually a post build test: bin/addonLintTest ' + require('./package.json').name",
|
||||||
|
|
|
@ -24,7 +24,6 @@ const {
|
||||||
MODIFIER_KEY,
|
MODIFIER_KEY,
|
||||||
} = require("./test/utils");
|
} = require("./test/utils");
|
||||||
|
|
||||||
|
|
||||||
const HELP = `
|
const HELP = `
|
||||||
env vars:
|
env vars:
|
||||||
|
|
||||||
|
@ -44,12 +43,11 @@ Future will clean up this interface a bit!
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const minimistHandler = {
|
const minimistHandler = {
|
||||||
boolean: [ "help" ],
|
boolean: ["help"],
|
||||||
alias: { h: "help", v: "version" },
|
alias: { h: "help", v: "version" },
|
||||||
"--": true,
|
"--": true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
(async() => {
|
(async() => {
|
||||||
const minimist = require("minimist");
|
const minimist = require("minimist");
|
||||||
const parsedArgs = minimist(process.argv.slice(2), minimistHandler);
|
const parsedArgs = minimist(process.argv.slice(2), minimistHandler);
|
||||||
|
@ -80,8 +78,9 @@ const minimistHandler = {
|
||||||
const openBrowserConsole = Key.chord(MODIFIER_KEY, Key.SHIFT, "j");
|
const openBrowserConsole = Key.chord(MODIFIER_KEY, Key.SHIFT, "j");
|
||||||
await urlBar.sendKeys(openBrowserConsole);
|
await urlBar.sendKeys(openBrowserConsole);
|
||||||
|
|
||||||
console.log("The addon should now be loaded and you should be able to interact with the addon in the newly opened Firefox instance.");
|
console.log(
|
||||||
|
"The addon should now be loaded and you should be able to interact with the addon in the newly opened Firefox instance.",
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,16 @@ const utils = require("./utils");
|
||||||
/* Part 1: Utilities */
|
/* Part 1: Utilities */
|
||||||
|
|
||||||
async function getShieldPingsAfterTimestamp(driver, ts) {
|
async function getShieldPingsAfterTimestamp(driver, ts) {
|
||||||
return utils.getTelemetryPings(driver, { type: ["shield-study", "shield-study-addon"], timestamp: ts });
|
return utils.getTelemetryPings(driver, {
|
||||||
|
type: ["shield-study", "shield-study-addon"],
|
||||||
|
timestamp: ts,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function summarizePings(pings) {
|
function summarizePings(pings) {
|
||||||
return pings.map(p => [p.payload.type, p.payload.data]);
|
return pings.map(p => [p.payload.type, p.payload.data]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function getNotification(driver) {
|
async function getNotification(driver) {
|
||||||
return utils.getChromeElementBy.tagName(driver, "notification");
|
return utils.getChromeElementBy.tagName(driver, "notification");
|
||||||
}
|
}
|
||||||
|
@ -33,7 +35,6 @@ async function getFirstButton(driver) {
|
||||||
return utils.getChromeElementBy.className(driver, "notification-button");
|
return utils.getChromeElementBy.className(driver, "notification-button");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Part 2: The Tests */
|
/* Part 2: The Tests */
|
||||||
|
|
||||||
describe("basic functional tests", function() {
|
describe("basic functional tests", function() {
|
||||||
|
@ -58,17 +59,14 @@ describe("basic functional tests", function() {
|
||||||
// collect sent pings
|
// collect sent pings
|
||||||
pings = await getShieldPingsAfterTimestamp(driver, beginTime);
|
pings = await getShieldPingsAfterTimestamp(driver, beginTime);
|
||||||
// console.log(pingsReport(pings).report);
|
// console.log(pingsReport(pings).report);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
after(async() => {
|
after(async() => {
|
||||||
driver.quit();
|
driver.quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async() => {});
|
||||||
});
|
afterEach(async() => {});
|
||||||
afterEach(async() => {
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Expected behaviour:
|
/* Expected behaviour:
|
||||||
|
|
||||||
|
@ -85,17 +83,33 @@ describe("basic functional tests", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("at least one shield-study telemetry ping with study_state=installed", async() => {
|
it("at least one shield-study telemetry ping with study_state=installed", async() => {
|
||||||
const foundPings = utils.searchTelemetry([
|
const foundPings = utils.searchTelemetry(
|
||||||
ping => ping.type === "shield-study" && ping.payload.data.study_state === "installed",
|
[
|
||||||
], pings);
|
ping =>
|
||||||
assert(foundPings.length > 0, "at least one shield-study telemetry ping with study_state=installed");
|
ping.type === "shield-study" &&
|
||||||
|
ping.payload.data.study_state === "installed",
|
||||||
|
],
|
||||||
|
pings,
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
foundPings.length > 0,
|
||||||
|
"at least one shield-study telemetry ping with study_state=installed",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("at least one shield-study telemetry ping with study_state=enter", async() => {
|
it("at least one shield-study telemetry ping with study_state=enter", async() => {
|
||||||
const foundPings = utils.searchTelemetry([
|
const foundPings = utils.searchTelemetry(
|
||||||
ping => ping.type === "shield-study" && ping.payload.data.study_state === "enter",
|
[
|
||||||
], pings);
|
ping =>
|
||||||
assert(foundPings.length > 0, "at least one shield-study telemetry ping with study_state=enter");
|
ping.type === "shield-study" &&
|
||||||
|
ping.payload.data.study_state === "enter",
|
||||||
|
],
|
||||||
|
pings,
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
foundPings.length > 0,
|
||||||
|
"at least one shield-study telemetry ping with study_state=enter",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("telemetry: has entered, installed, etc", function() {
|
it("telemetry: has entered, installed, etc", function() {
|
||||||
|
@ -105,21 +119,21 @@ describe("basic functional tests", function() {
|
||||||
[
|
[
|
||||||
"shield-study-addon",
|
"shield-study-addon",
|
||||||
{
|
{
|
||||||
"attributes": {
|
attributes: {
|
||||||
"event": "introduction-shown",
|
event: "introduction-shown",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"shield-study",
|
"shield-study",
|
||||||
{
|
{
|
||||||
"study_state": "installed",
|
study_state: "installed",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"shield-study",
|
"shield-study",
|
||||||
{
|
{
|
||||||
"study_state": "enter",
|
study_state: "enter",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -129,7 +143,9 @@ describe("basic functional tests", function() {
|
||||||
describe("introduction / orientation bar", function() {
|
describe("introduction / orientation bar", function() {
|
||||||
it("exists, carries study config", async() => {
|
it("exists, carries study config", async() => {
|
||||||
const notice = await getNotification(driver);
|
const notice = await getNotification(driver);
|
||||||
const noticeConfig = JSON.parse(await notice.getAttribute("data-study-config"));
|
const noticeConfig = JSON.parse(
|
||||||
|
await notice.getAttribute("data-study-config"),
|
||||||
|
);
|
||||||
assert(noticeConfig.name);
|
assert(noticeConfig.name);
|
||||||
assert(noticeConfig.weight);
|
assert(noticeConfig.weight);
|
||||||
});
|
});
|
||||||
|
@ -153,15 +169,14 @@ describe("basic functional tests", function() {
|
||||||
[
|
[
|
||||||
"shield-study-addon",
|
"shield-study-addon",
|
||||||
{
|
{
|
||||||
"attributes": {
|
attributes: {
|
||||||
"event": "introduction-accept",
|
event: "introduction-accept",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
// this would add new telemetry
|
// this would add new telemetry
|
||||||
assert.deepEqual(expected, observed, "telemetry pings do not match");
|
assert.deepEqual(expected, observed, "telemetry pings do not match");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("TBD click on NO uninstalls addon", async() => {
|
it("TBD click on NO uninstalls addon", async() => {
|
||||||
|
|
|
@ -13,21 +13,21 @@ const { spawn } = require("child_process");
|
||||||
|
|
||||||
// Promise wrapper around childProcess.spawn()
|
// Promise wrapper around childProcess.spawn()
|
||||||
function spawnProcess(command, args) {
|
function spawnProcess(command, args) {
|
||||||
return new Promise((resolve) => {
|
return new Promise(resolve => {
|
||||||
const childProcess = spawn(command, args);
|
const childProcess = spawn(command, args);
|
||||||
const stderrArray = [];
|
const stderrArray = [];
|
||||||
const stdoutArray = [];
|
const stdoutArray = [];
|
||||||
|
|
||||||
childProcess.stdout.on("data", (data) => {
|
childProcess.stdout.on("data", data => {
|
||||||
stdoutArray.push(data.toString()); // data is of type Buffer
|
stdoutArray.push(data.toString()); // data is of type Buffer
|
||||||
});
|
});
|
||||||
|
|
||||||
childProcess.stderr.on("data", (data) => {
|
childProcess.stderr.on("data", data => {
|
||||||
// TODO reject upon error?
|
// TODO reject upon error?
|
||||||
stderrArray.push(data.toString()); // data is of type Buffer
|
stderrArray.push(data.toString()); // data is of type Buffer
|
||||||
});
|
});
|
||||||
|
|
||||||
childProcess.on("close", (code) => {
|
childProcess.on("close", code => {
|
||||||
// TODO reject upon error?
|
// TODO reject upon error?
|
||||||
console.log("Test suite completed.");
|
console.log("Test suite completed.");
|
||||||
resolve({ code, stdoutArray, stderrArray });
|
resolve({ code, stdoutArray, stderrArray });
|
||||||
|
@ -44,7 +44,9 @@ async function main() {
|
||||||
console.log(`Currently running test suite #${i}.`);
|
console.log(`Currently running test suite #${i}.`);
|
||||||
const childProcesses = [];
|
const childProcesses = [];
|
||||||
// NOTE Parallel tests seem to introduce more errors.
|
// NOTE Parallel tests seem to introduce more errors.
|
||||||
childProcesses.push(spawnProcess("npm", ["run", "--silent", "harness_test"]));
|
childProcesses.push(
|
||||||
|
spawnProcess("npm", ["run", "--silent", "harness_test"]),
|
||||||
|
);
|
||||||
|
|
||||||
// TODO Promise.all() will reject upon a single error, is this an issue?
|
// TODO Promise.all() will reject upon a single error, is this an issue?
|
||||||
try {
|
try {
|
||||||
|
@ -57,11 +59,13 @@ async function main() {
|
||||||
const mochaOutput = JSON.parse(rawOutput.join(""));
|
const mochaOutput = JSON.parse(rawOutput.join(""));
|
||||||
for (const failedTest of mochaOutput.failures) {
|
for (const failedTest of mochaOutput.failures) {
|
||||||
console.log(failedTest.err);
|
console.log(failedTest.err);
|
||||||
if (!(failedTestCounts.has(failedTest.fullTitle))) {
|
if (!failedTestCounts.has(failedTest.fullTitle)) {
|
||||||
failedTestCounts.set(failedTest.fullTitle, 0);
|
failedTestCounts.set(failedTest.fullTitle, 0);
|
||||||
}
|
}
|
||||||
failedTestCounts.set(failedTest.fullTitle,
|
failedTestCounts.set(
|
||||||
failedTestCounts.get(failedTest.fullTitle) + 1);
|
failedTest.fullTitle,
|
||||||
|
failedTestCounts.get(failedTest.fullTitle) + 1,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`JSON parsing error: ${e}`);
|
console.log(`JSON parsing error: ${e}`);
|
||||||
|
@ -74,12 +78,15 @@ async function main() {
|
||||||
}
|
}
|
||||||
console.log(failedTestCounts);
|
console.log(failedTestCounts);
|
||||||
for (const pair of failedTestCounts) {
|
for (const pair of failedTestCounts) {
|
||||||
fs.appendFile(`test_harness_output_${new Date().toISOString()}.txt`, `${pair[0]}: ${pair[1]}\n`,
|
fs.appendFile(
|
||||||
(err) => {
|
`test_harness_output_${new Date().toISOString()}.txt`,
|
||||||
|
`${pair[0]}: ${pair[1]}\n`,
|
||||||
|
err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(`fs.writeFile errror: ${err}`);
|
console.log(`fs.writeFile errror: ${err}`);
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
126
test/utils.js
126
test/utils.js
|
@ -42,12 +42,12 @@ const FIREFOX_PREFERENCES = {
|
||||||
"extensions.button_icon_preference.variation": "kittens",
|
"extensions.button_icon_preference.variation": "kittens",
|
||||||
|
|
||||||
/** WARNING: gecko webdriver sets many additional prefs at:
|
/** WARNING: gecko webdriver sets many additional prefs at:
|
||||||
* https://dxr.mozilla.org/mozilla-central/source/testing/geckodriver/src/prefs.rs
|
* https://dxr.mozilla.org/mozilla-central/source/testing/geckodriver/src/prefs.rs
|
||||||
*
|
*
|
||||||
* In, particular, this DISABLES actual telemetry uploading
|
* In, particular, this DISABLES actual telemetry uploading
|
||||||
* ("toolkit.telemetry.server", Pref::new("https://%(server)s/dummy/telemetry/")),
|
* ("toolkit.telemetry.server", Pref::new("https://%(server)s/dummy/telemetry/")),
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
// useful if we need to test on a specific version of Firefox
|
// useful if we need to test on a specific version of Firefox
|
||||||
|
@ -66,14 +66,14 @@ async function promiseActualBinary(binary) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses process.env.FIREFOX_BINARY
|
* Uses process.env.FIREFOX_BINARY
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
module.exports.promiseSetupDriver = async() => {
|
module.exports.promiseSetupDriver = async() => {
|
||||||
const profile = new firefox.Profile();
|
const profile = new firefox.Profile();
|
||||||
|
|
||||||
// TODO, allow 'actually send telemetry' here.
|
// TODO, allow 'actually send telemetry' here.
|
||||||
Object.keys(FIREFOX_PREFERENCES).forEach((key) => {
|
Object.keys(FIREFOX_PREFERENCES).forEach(key => {
|
||||||
profile.setPreference(key, FIREFOX_PREFERENCES[key]);
|
profile.setPreference(key, FIREFOX_PREFERENCES[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -85,7 +85,9 @@ module.exports.promiseSetupDriver = async() => {
|
||||||
.forBrowser("firefox")
|
.forBrowser("firefox")
|
||||||
.setFirefoxOptions(options);
|
.setFirefoxOptions(options);
|
||||||
|
|
||||||
const binaryLocation = await promiseActualBinary(process.env.FIREFOX_BINARY || "nightly");
|
const binaryLocation = await promiseActualBinary(
|
||||||
|
process.env.FIREFOX_BINARY || "nightly",
|
||||||
|
);
|
||||||
|
|
||||||
// console.log(binaryLocation);
|
// console.log(binaryLocation);
|
||||||
await options.setBinary(new firefox.Binary(binaryLocation));
|
await options.setBinary(new firefox.Binary(binaryLocation));
|
||||||
|
@ -96,25 +98,24 @@ module.exports.promiseSetupDriver = async() => {
|
||||||
return driver;
|
return driver;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* let's actually just make this a constant */
|
/* let's actually just make this a constant */
|
||||||
const MODIFIER_KEY = (function getModifierKey() {
|
const MODIFIER_KEY = (function getModifierKey() {
|
||||||
const modifierKey = process.platform === "darwin" ?
|
const modifierKey =
|
||||||
webdriver.Key.COMMAND : webdriver.Key.CONTROL;
|
process.platform === "darwin"
|
||||||
|
? webdriver.Key.COMMAND
|
||||||
|
: webdriver.Key.CONTROL;
|
||||||
return modifierKey;
|
return modifierKey;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
module.exports.MODIFIER_KEY = MODIFIER_KEY;
|
module.exports.MODIFIER_KEY = MODIFIER_KEY;
|
||||||
|
|
||||||
|
|
||||||
// TODO glind general wrapper for 'async with callback'?
|
// TODO glind general wrapper for 'async with callback'?
|
||||||
|
|
||||||
|
|
||||||
/* Firefox UI helper functions */
|
/* Firefox UI helper functions */
|
||||||
|
|
||||||
// such as: "social-share-button"
|
// such as: "social-share-button"
|
||||||
module.exports.addButtonFromCustomizePanel = async(driver, buttonId) =>
|
module.exports.addButtonFromCustomizePanel = async(driver, buttonId) =>
|
||||||
driver.executeAsyncScript((callback) => {
|
driver.executeAsyncScript(callback => {
|
||||||
// see https://dxr.mozilla.org/mozilla-central/rev/211d4dd61025c0a40caea7a54c9066e051bdde8c/browser/base/content/browser-social.js#193
|
// see https://dxr.mozilla.org/mozilla-central/rev/211d4dd61025c0a40caea7a54c9066e051bdde8c/browser/base/content/browser-social.js#193
|
||||||
Components.utils.import("resource:///modules/CustomizableUI.jsm");
|
Components.utils.import("resource:///modules/CustomizableUI.jsm");
|
||||||
CustomizableUI.addWidgetToArea(buttonId, CustomizableUI.AREA_NAVBAR);
|
CustomizableUI.addWidgetToArea(buttonId, CustomizableUI.AREA_NAVBAR);
|
||||||
|
@ -123,7 +124,7 @@ module.exports.addButtonFromCustomizePanel = async(driver, buttonId) =>
|
||||||
|
|
||||||
module.exports.removeButtonFromNavbar = async(driver, buttonId) => {
|
module.exports.removeButtonFromNavbar = async(driver, buttonId) => {
|
||||||
try {
|
try {
|
||||||
await driver.executeAsyncScript((callback) => {
|
await driver.executeAsyncScript(callback => {
|
||||||
Components.utils.import("resource:///modules/CustomizableUI.jsm");
|
Components.utils.import("resource:///modules/CustomizableUI.jsm");
|
||||||
CustomizableUI.removeWidgetFromArea(buttonId);
|
CustomizableUI.removeWidgetFromArea(buttonId);
|
||||||
callback();
|
callback();
|
||||||
|
@ -136,7 +137,7 @@ module.exports.removeButtonFromNavbar = async(driver, buttonId) => {
|
||||||
if (e.name === "TimeoutError") {
|
if (e.name === "TimeoutError") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
throw (e);
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,17 +148,29 @@ module.exports.installAddon = async(driver, fileLocation) => {
|
||||||
fileLocation = fileLocation || path.join(process.cwd(), process.env.XPI);
|
fileLocation = fileLocation || path.join(process.cwd(), process.env.XPI);
|
||||||
|
|
||||||
const executor = driver.getExecutor();
|
const executor = driver.getExecutor();
|
||||||
executor.defineCommand("installAddon", "POST", "/session/:sessionId/moz/addon/install");
|
executor.defineCommand(
|
||||||
|
"installAddon",
|
||||||
|
"POST",
|
||||||
|
"/session/:sessionId/moz/addon/install",
|
||||||
|
);
|
||||||
const installCmd = new cmd.Command("installAddon");
|
const installCmd = new cmd.Command("installAddon");
|
||||||
|
|
||||||
const session = await driver.getSession();
|
const session = await driver.getSession();
|
||||||
installCmd.setParameters({ sessionId: session.getId(), path: fileLocation, temporary: true });
|
installCmd.setParameters({
|
||||||
|
sessionId: session.getId(),
|
||||||
|
path: fileLocation,
|
||||||
|
temporary: true,
|
||||||
|
});
|
||||||
return executor.execute(installCmd);
|
return executor.execute(installCmd);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.uninstallAddon = async(driver, id) => {
|
module.exports.uninstallAddon = async(driver, id) => {
|
||||||
const executor = driver.getExecutor();
|
const executor = driver.getExecutor();
|
||||||
executor.defineCommand("uninstallAddon", "POST", "/session/:sessionId/moz/addon/uninstall");
|
executor.defineCommand(
|
||||||
|
"uninstallAddon",
|
||||||
|
"POST",
|
||||||
|
"/session/:sessionId/moz/addon/uninstall",
|
||||||
|
);
|
||||||
const uninstallCmd = new cmd.Command("uninstallAddon");
|
const uninstallCmd = new cmd.Command("uninstallAddon");
|
||||||
|
|
||||||
const session = await driver.getSession();
|
const session = await driver.getSession();
|
||||||
|
@ -165,7 +178,6 @@ module.exports.uninstallAddon = async(driver, id) => {
|
||||||
await executor.execute(uninstallCmd);
|
await executor.execute(uninstallCmd);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* this is NOT WORKING FOR UNKNOWN HARD TO EXLAIN REASONS
|
/* this is NOT WORKING FOR UNKNOWN HARD TO EXLAIN REASONS
|
||||||
=> Uncaught WebDriverError: InternalError: too much recursion
|
=> Uncaught WebDriverError: InternalError: too much recursion
|
||||||
module.exports.allAddons = async(driver) => {
|
module.exports.allAddons = async(driver) => {
|
||||||
|
@ -179,20 +191,20 @@ module.exports.allAddons = async(driver) => {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Returns array of pings of type `type` in reverse sorted order by timestamp
|
/** Returns array of pings of type `type` in reverse sorted order by timestamp
|
||||||
* first element is most recent ping
|
* first element is most recent ping
|
||||||
*
|
*
|
||||||
* as seen in shield-study-addon-util's `utils.jsm`
|
* as seen in shield-study-addon-util's `utils.jsm`
|
||||||
* options
|
* options
|
||||||
* - type: string or array of ping types
|
* - type: string or array of ping types
|
||||||
* - n: positive integer. at most n pings.
|
* - n: positive integer. at most n pings.
|
||||||
* - timestamp: only pings after this timestamp.
|
* - timestamp: only pings after this timestamp.
|
||||||
* - headersOnly: boolean, just the 'headers' for the pings, not the full bodies.
|
* - headersOnly: boolean, just the 'headers' for the pings, not the full bodies.
|
||||||
*/
|
*/
|
||||||
module.exports.getTelemetryPings = async(driver, passedOptions) => {
|
module.exports.getTelemetryPings = async(driver, passedOptions) => {
|
||||||
// callback is how you get the return back from the script
|
// callback is how you get the return back from the script
|
||||||
return driver.executeAsyncScript(async(options, callback) => {
|
return driver.executeAsyncScript(async(options, callback) => {
|
||||||
let {type} = options;
|
let { type } = options;
|
||||||
const { n, timestamp, headersOnly} = options;
|
const { n, timestamp, headersOnly } = options;
|
||||||
Components.utils.import("resource://gre/modules/TelemetryArchive.jsm");
|
Components.utils.import("resource://gre/modules/TelemetryArchive.jsm");
|
||||||
// {type, id, timestampCreated}
|
// {type, id, timestampCreated}
|
||||||
let pings = await TelemetryArchive.promiseArchivedPingList();
|
let pings = await TelemetryArchive.promiseArchivedPingList();
|
||||||
|
@ -207,49 +219,57 @@ module.exports.getTelemetryPings = async(driver, passedOptions) => {
|
||||||
|
|
||||||
pings.sort((a, b) => b.timestampCreated - a.timestampCreated);
|
pings.sort((a, b) => b.timestampCreated - a.timestampCreated);
|
||||||
if (n) pings = pings.slice(0, n);
|
if (n) pings = pings.slice(0, n);
|
||||||
const pingData = headersOnly ? pings : pings.map(ping => TelemetryArchive.promiseArchivedPingById(ping.id));
|
const pingData = headersOnly
|
||||||
|
? pings
|
||||||
|
: pings.map(ping => TelemetryArchive.promiseArchivedPingById(ping.id));
|
||||||
|
|
||||||
callback(await Promise.all(pingData));
|
callback(await Promise.all(pingData));
|
||||||
}, passedOptions);
|
}, passedOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO glind, this interface feels janky
|
// TODO glind, this interface feels janky
|
||||||
// this feels like it wants to be $ like.
|
// this feels like it wants to be $ like.
|
||||||
// not obvious right now, moving on!
|
// not obvious right now, moving on!
|
||||||
class getChromeElementBy {
|
class getChromeElementBy {
|
||||||
static async _get1(driver, method, selector ) {
|
static async _get1(driver, method, selector) {
|
||||||
driver.setContext(Context.CHROME);
|
driver.setContext(Context.CHROME);
|
||||||
try {
|
try {
|
||||||
return await driver.wait(until.elementLocated(
|
return await driver.wait(
|
||||||
By[method](selector)), 1000);
|
until.elementLocated(By[method](selector)),
|
||||||
|
1000,
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// if there an error, the button was not found
|
// if there an error, the button was not found
|
||||||
console.error(e);
|
console.error(e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async id(driver, id) { return this._get1(driver, "id", id); }
|
static async id(driver, id) {
|
||||||
|
return this._get1(driver, "id", id);
|
||||||
|
}
|
||||||
|
|
||||||
static async className(driver, className) { return this._get1(driver, "className", className); }
|
static async className(driver, className) {
|
||||||
|
return this._get1(driver, "className", className);
|
||||||
|
}
|
||||||
|
|
||||||
static async tagName(driver, tagName) { return this._get1(driver, "tagName", tagName); }
|
static async tagName(driver, tagName) {
|
||||||
|
return this._get1(driver, "tagName", tagName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module.exports.getChromeElementBy = getChromeElementBy;
|
module.exports.getChromeElementBy = getChromeElementBy;
|
||||||
|
|
||||||
module.exports.promiseUrlBar = (driver) => {
|
module.exports.promiseUrlBar = driver => {
|
||||||
driver.setContext(Context.CHROME);
|
driver.setContext(Context.CHROME);
|
||||||
return driver.wait(until.elementLocated(
|
return driver.wait(until.elementLocated(By.id("urlbar")), 1000);
|
||||||
By.id("urlbar")), 1000);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.takeScreenshot = async(driver, filepath = "./screenshot.png") => {
|
module.exports.takeScreenshot = async(
|
||||||
|
driver,
|
||||||
|
filepath = "./screenshot.png",
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
const data = await driver.takeScreenshot();
|
const data = await driver.takeScreenshot();
|
||||||
return await Fs.outputFile(filepath,
|
return await Fs.outputFile(filepath, data, "base64");
|
||||||
data, "base64");
|
|
||||||
} catch (screenshotError) {
|
} catch (screenshotError) {
|
||||||
throw screenshotError;
|
throw screenshotError;
|
||||||
}
|
}
|
||||||
|
@ -275,7 +295,9 @@ module.exports.searchTelemetry = (conditionArray, telemetryArray) => {
|
||||||
const resultingPings = [];
|
const resultingPings = [];
|
||||||
for (const condition of conditionArray) {
|
for (const condition of conditionArray) {
|
||||||
const index = telemetryArray.findIndex(ping => condition(ping));
|
const index = telemetryArray.findIndex(ping => condition(ping));
|
||||||
if (index === -1) { throw new SearchError(condition); }
|
if (index === -1) {
|
||||||
|
throw new SearchError(condition);
|
||||||
|
}
|
||||||
resultingPings.push(telemetryArray[index]);
|
resultingPings.push(telemetryArray[index]);
|
||||||
}
|
}
|
||||||
return resultingPings;
|
return resultingPings;
|
||||||
|
@ -328,7 +350,6 @@ module.exports.searchTelemetry = (conditionArray, telemetryArray) => {
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
||||||
// module.exports.testPanel = async(driver, panelId) => {
|
// module.exports.testPanel = async(driver, panelId) => {
|
||||||
// driver.setContext(Context.CHROME);
|
// driver.setContext(Context.CHROME);
|
||||||
// try { // if we can't find the panel, return false
|
// try { // if we can't find the panel, return false
|
||||||
|
@ -351,7 +372,6 @@ module.exports.searchTelemetry = (conditionArray, telemetryArray) => {
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
||||||
// module.exports.closePanel = async(driver, target = null) => {
|
// module.exports.closePanel = async(driver, target = null) => {
|
||||||
// if (target !== null) {
|
// if (target !== null) {
|
||||||
// target.sendKeys(webdriver.Key.ESCAPE);
|
// target.sendKeys(webdriver.Key.ESCAPE);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче