mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Adding firefox to test suite (#17195)
* Created general driver to accept an argument select the driver to run. * Added environment variable for driver, changed package.json to use custim leadfoot, and made changes to browserdriver to use any driver. * Made changes per PR. * Fixed all nits.
This commit is contained in:
parent
dc0ce9e2b9
commit
a31ec148f4
13 changed files with 213 additions and 106 deletions
|
@ -242,6 +242,7 @@
|
||||||
"event-stream": "3.3.2",
|
"event-stream": "3.3.2",
|
||||||
"expect.js": "0.3.1",
|
"expect.js": "0.3.1",
|
||||||
"faker": "1.1.0",
|
"faker": "1.1.0",
|
||||||
|
"geckodriver": "1.10.0",
|
||||||
"getopts": "2.0.0",
|
"getopts": "2.0.0",
|
||||||
"grunt": "1.0.1",
|
"grunt": "1.0.1",
|
||||||
"grunt-aws-s3": "0.14.5",
|
"grunt-aws-s3": "0.14.5",
|
||||||
|
@ -269,7 +270,7 @@
|
||||||
"karma-junit-reporter": "1.2.0",
|
"karma-junit-reporter": "1.2.0",
|
||||||
"karma-mocha": "1.3.0",
|
"karma-mocha": "1.3.0",
|
||||||
"karma-safari-launcher": "1.0.0",
|
"karma-safari-launcher": "1.0.0",
|
||||||
"leadfoot": "1.7.1",
|
"leadfoot": "silne30/leadfoot#validation_for_response_in_ff58",
|
||||||
"license-checker": "^16.0.0",
|
"license-checker": "^16.0.0",
|
||||||
"load-grunt-config": "0.19.2",
|
"load-grunt-config": "0.19.2",
|
||||||
"makelogs": "^4.0.4",
|
"makelogs": "^4.0.4",
|
||||||
|
|
|
@ -94,6 +94,11 @@ export const schema = Joi.object().keys({
|
||||||
url: Joi.string().uri({ scheme: /https?/ }).default('http://localhost:9515')
|
url: Joi.string().uri({ scheme: /https?/ }).default('http://localhost:9515')
|
||||||
}).default(),
|
}).default(),
|
||||||
|
|
||||||
|
firefoxdriver: Joi.object().keys({
|
||||||
|
url: Joi.string().uri({ scheme: /https?/ }).default('http://localhost:2828')
|
||||||
|
}).default(),
|
||||||
|
|
||||||
|
|
||||||
// definition of apps that work with `common.navigateToApp()`
|
// definition of apps that work with `common.navigateToApp()`
|
||||||
apps: Joi.object().pattern(
|
apps: Joi.object().pattern(
|
||||||
ID_PATTERN,
|
ID_PATTERN,
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
import { createLocalChromedriverApi } from './chromedriver_local_api';
|
import { createLocalBrowserDriverApi } from './browser_driver_local_api';
|
||||||
import { createRemoteChromedriverApi } from './chromedriver_remote_api';
|
import { createRemoteBrowserDriverApi } from './browser_driver_remote_api';
|
||||||
import { ping } from './ping';
|
import { ping } from './ping';
|
||||||
|
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Api for interacting with a local or remote instance of Chromedriver
|
* Api for interacting with a local or remote instance of a browser
|
||||||
*
|
*
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
*/
|
*/
|
||||||
export class ChromedriverApi extends EventEmitter {
|
export class BrowserDriverApi extends EventEmitter {
|
||||||
static async factory(log, url) {
|
static async factory(log, url, browserType) {
|
||||||
return (await ping(url))
|
return (await ping(url))
|
||||||
? createRemoteChromedriverApi(log, url)
|
? createRemoteBrowserDriverApi(log, url)
|
||||||
: createLocalChromedriverApi(log, url);
|
: createLocalBrowserDriverApi(log, url, browserType);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
|
@ -25,19 +25,22 @@ export class ChromedriverApi extends EventEmitter {
|
||||||
url,
|
url,
|
||||||
start = noop,
|
start = noop,
|
||||||
stop = noop,
|
stop = noop,
|
||||||
|
requiredCapabilities,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
throw new TypeError('url is a required parameter');
|
throw new TypeError('url is a required parameter');
|
||||||
}
|
}
|
||||||
|
this._requiredCapabilities = requiredCapabilities;
|
||||||
this._url = url;
|
this._url = url;
|
||||||
this._state = undefined;
|
this._state = undefined;
|
||||||
this._callCustomStart = () => start(this);
|
this._callCustomStart = () => start(this);
|
||||||
this._callCustomStop = () => stop(this);
|
this._callCustomStop = () => stop(this);
|
||||||
this._beforeStopFns = [];
|
this._beforeStopFns = [];
|
||||||
}
|
}
|
||||||
|
getRequiredCapabilities() {
|
||||||
|
return this._requiredCapabilities;
|
||||||
|
}
|
||||||
getUrl() {
|
getUrl() {
|
||||||
return this._url;
|
return this._url;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +55,7 @@ export class ChromedriverApi extends EventEmitter {
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
if (this._state !== undefined) {
|
if (this._state !== undefined) {
|
||||||
throw new Error('Chromedriver can only be started once');
|
throw new Error('Driver can only be started once');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._state = 'started';
|
this._state = 'started';
|
||||||
|
@ -61,7 +64,7 @@ export class ChromedriverApi extends EventEmitter {
|
||||||
|
|
||||||
async stop() {
|
async stop() {
|
||||||
if (this._state !== 'started') {
|
if (this._state !== 'started') {
|
||||||
throw new Error('Chromedriver can only be stopped after being started');
|
throw new Error('Driver can only be stopped after being started');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._state = 'stopped';
|
this._state = 'stopped';
|
|
@ -0,0 +1,75 @@
|
||||||
|
import { spawn } from 'child_process';
|
||||||
|
import { parse as parseUrl } from 'url';
|
||||||
|
|
||||||
|
import treeKill from 'tree-kill';
|
||||||
|
import { delay, fromNode as fcb } from 'bluebird';
|
||||||
|
import { path as CHROMEDRIVER_EXEC } from 'chromedriver';
|
||||||
|
import { path as FIREFOXDRIVER_EXEC } from 'geckodriver';
|
||||||
|
|
||||||
|
import { ping } from './ping';
|
||||||
|
import { BrowserDriverApi } from './browser_driver_api';
|
||||||
|
const START_TIMEOUT = 15000;
|
||||||
|
const PING_INTERVAL = 500;
|
||||||
|
|
||||||
|
export function createLocalBrowserDriverApi(log, url, browser) {
|
||||||
|
let runningDriver = null;
|
||||||
|
const driverName = browser + 'driver';
|
||||||
|
switch (browser) {
|
||||||
|
case 'firefox':
|
||||||
|
runningDriver = FIREFOXDRIVER_EXEC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
runningDriver = CHROMEDRIVER_EXEC;
|
||||||
|
}
|
||||||
|
let proc = null;
|
||||||
|
|
||||||
|
return new BrowserDriverApi({
|
||||||
|
url,
|
||||||
|
requiredCapabilities: Object.create({ browserType: browser }),
|
||||||
|
|
||||||
|
async start(api) {
|
||||||
|
const { port } = parseUrl(url);
|
||||||
|
log.debug('Starting local ' + driverName + ' at port %d', port);
|
||||||
|
|
||||||
|
proc = spawn(runningDriver, [`--port=${port}`], {
|
||||||
|
stdio: ['ignore', 'pipe', 'pipe'],
|
||||||
|
});
|
||||||
|
|
||||||
|
proc.stdout.on('data', chunk => {
|
||||||
|
log.debug('[' + driverName + ':stdout]', chunk.toString('utf8').trim());
|
||||||
|
});
|
||||||
|
proc.stderr.on('data', chunk => {
|
||||||
|
log.debug('[' + driverName + ':stderr]', chunk.toString('utf8').trim());
|
||||||
|
});
|
||||||
|
|
||||||
|
proc.on('exit', (code) => {
|
||||||
|
if (!api.isStopped() || code > 0) {
|
||||||
|
api.emit('error', new Error(driverName + ` exited with code ${code}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const pingsStartedAt = Date.now();
|
||||||
|
while (true) {
|
||||||
|
log.debug('[' + driverName + ':ping] attempting to reach at %j', url);
|
||||||
|
if (await ping(url)) {
|
||||||
|
log.debug('[' + driverName + ':ping] success');
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
log.debug('[' + driverName + ':ping] failure');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Date.now() - pingsStartedAt) < START_TIMEOUT) {
|
||||||
|
log.debug('[' + driverName + ':ping] waiting for %d before next ping', PING_INTERVAL);
|
||||||
|
await delay(PING_INTERVAL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(driverName + ` did not start within the ${START_TIMEOUT}ms timeout`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async stop() {
|
||||||
|
await fcb(cb => treeKill(proc.pid, undefined, cb));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { BrowserDriverApi } from './browser_driver_api';
|
||||||
|
|
||||||
|
export function createRemoteBrowserDriverApi(log, url) {
|
||||||
|
return new BrowserDriverApi({
|
||||||
|
url,
|
||||||
|
|
||||||
|
start() {
|
||||||
|
log.info(`Reusing instance at %j`, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export { BrowserDriverApi } from './browser_driver_api';
|
|
@ -1,64 +0,0 @@
|
||||||
import { spawn } from 'child_process';
|
|
||||||
import { parse as parseUrl } from 'url';
|
|
||||||
|
|
||||||
import treeKill from 'tree-kill';
|
|
||||||
import { delay, fromNode as fcb } from 'bluebird';
|
|
||||||
import { path as CHROMEDRIVER_EXEC } from 'chromedriver';
|
|
||||||
|
|
||||||
import { ping } from './ping';
|
|
||||||
import { ChromedriverApi } from './chromedriver_api';
|
|
||||||
const START_TIMEOUT = 15000;
|
|
||||||
const PING_INTERVAL = 500;
|
|
||||||
|
|
||||||
export function createLocalChromedriverApi(log, url) {
|
|
||||||
let proc = null;
|
|
||||||
|
|
||||||
return new ChromedriverApi({
|
|
||||||
url,
|
|
||||||
|
|
||||||
async start(api) {
|
|
||||||
const { port } = parseUrl(url);
|
|
||||||
log.info('Starting local chromedriver at port %d', port);
|
|
||||||
|
|
||||||
proc = spawn(CHROMEDRIVER_EXEC, [`--port=${port}`], {
|
|
||||||
stdio: ['ignore', 'pipe', 'pipe'],
|
|
||||||
});
|
|
||||||
|
|
||||||
proc.stdout.on('data', chunk => {
|
|
||||||
log.debug('[chromedriver:stdout]', chunk.toString('utf8').trim());
|
|
||||||
});
|
|
||||||
proc.stderr.on('data', chunk => {
|
|
||||||
log.debug('[chromedriver:stderr]', chunk.toString('utf8').trim());
|
|
||||||
});
|
|
||||||
|
|
||||||
proc.on('exit', (code) => {
|
|
||||||
if (!api.isStopped() || code > 0) {
|
|
||||||
api.emit('error', new Error(`Chromedriver exited with code ${code}`));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const pingsStartedAt = Date.now();
|
|
||||||
while (true) {
|
|
||||||
log.debug('[chromedriver:ping] attempting to reach chromedriver at %j', url);
|
|
||||||
if (await ping(url)) {
|
|
||||||
log.debug('[chromedriver:ping] success');
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
log.debug('[chromedriver:ping] failure');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Date.now() - pingsStartedAt) < START_TIMEOUT) {
|
|
||||||
log.debug('[chromedriver:ping] waiting for %d before next ping', PING_INTERVAL);
|
|
||||||
await delay(PING_INTERVAL);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`Chromedriver did not start within the ${START_TIMEOUT}ms timeout`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
await fcb(cb => treeKill(proc.pid, undefined, cb));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
import { ChromedriverApi } from './chromedriver_api';
|
|
||||||
|
|
||||||
export function createRemoteChromedriverApi(log, url) {
|
|
||||||
return new ChromedriverApi({
|
|
||||||
url,
|
|
||||||
|
|
||||||
start() {
|
|
||||||
log.info(`Reusing instance at %j`, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
export { ChromedriverApi } from './chromedriver_api';
|
|
|
@ -8,15 +8,14 @@ const SECOND = 1000;
|
||||||
const MINUTE = 60 * SECOND;
|
const MINUTE = 60 * SECOND;
|
||||||
|
|
||||||
let attemptCounter = 0;
|
let attemptCounter = 0;
|
||||||
async function attemptToCreateCommand(log, server, chromedriverApi) {
|
async function attemptToCreateCommand(log, server, driverApi) {
|
||||||
const attemptId = ++attemptCounter;
|
const attemptId = ++attemptCounter;
|
||||||
|
|
||||||
log.debug('[leadfoot:command] Creating session');
|
log.debug('[leadfoot:command] Creating session');
|
||||||
const session = await server.createSession({ browserName: 'chrome' });
|
const session = await server.createSession({}, driverApi.getRequiredCapabilities());
|
||||||
if (attemptId !== attemptCounter) return; // abort
|
if (attemptId !== attemptCounter) return; // abort
|
||||||
|
|
||||||
log.debug('[leadfoot:command] Registerying session for teardown');
|
log.debug('[leadfoot:command] Registerying session for teardown');
|
||||||
chromedriverApi.beforeStop(async () => session.quit());
|
driverApi.beforeStop(async () => session.quit());
|
||||||
if (attemptId !== attemptCounter) return; // abort
|
if (attemptId !== attemptCounter) return; // abort
|
||||||
|
|
||||||
log.debug('[leadfoot:command] Completing session capabilities');
|
log.debug('[leadfoot:command] Completing session capabilities');
|
||||||
|
@ -29,7 +28,7 @@ async function attemptToCreateCommand(log, server, chromedriverApi) {
|
||||||
return { command: new Command(session) };
|
return { command: new Command(session) };
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function initLeadfootCommand({ log, chromedriverApi }) {
|
export async function initLeadfootCommand({ log, browserDriverApi }) {
|
||||||
return await Promise.race([
|
return await Promise.race([
|
||||||
(async () => {
|
(async () => {
|
||||||
await delay(2 * MINUTE);
|
await delay(2 * MINUTE);
|
||||||
|
@ -41,7 +40,7 @@ export async function initLeadfootCommand({ log, chromedriverApi }) {
|
||||||
// backend (chromedriver in this case). it helps with session management
|
// backend (chromedriver in this case). it helps with session management
|
||||||
// and all communication to the remote browser go through it, so we shim
|
// and all communication to the remote browser go through it, so we shim
|
||||||
// some of it's methods to enable very verbose logging.
|
// some of it's methods to enable very verbose logging.
|
||||||
const server = initVerboseRemoteLogging(log, new Server(chromedriverApi.getUrl()));
|
const server = initVerboseRemoteLogging(log, new Server(browserDriverApi.getUrl()));
|
||||||
|
|
||||||
// by default, calling server.createSession() automatically fixes the webdriver
|
// by default, calling server.createSession() automatically fixes the webdriver
|
||||||
// "capabilities" hash so that leadfoot knows the hoops it has to jump through
|
// "capabilities" hash so that leadfoot knows the hoops it has to jump through
|
||||||
|
@ -59,7 +58,7 @@ export async function initLeadfootCommand({ log, chromedriverApi }) {
|
||||||
while (true) {
|
while (true) {
|
||||||
const command = await Promise.race([
|
const command = await Promise.race([
|
||||||
delay(30 * SECOND),
|
delay(30 * SECOND),
|
||||||
attemptToCreateCommand(log, server, chromedriverApi)
|
attemptToCreateCommand(log, server, browserDriverApi)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!command) {
|
if (!command) {
|
||||||
|
|
|
@ -1,18 +1,24 @@
|
||||||
import { initLeadfootCommand } from './leadfoot_command';
|
import { initLeadfootCommand } from './leadfoot_command';
|
||||||
import { createRemoteInterceptors } from './interceptors';
|
import { createRemoteInterceptors } from './interceptors';
|
||||||
import { ChromedriverApi } from './chromedriver_api';
|
import { BrowserDriverApi } from './browser_driver_api';
|
||||||
|
|
||||||
export async function RemoteProvider({ getService }) {
|
export async function RemoteProvider({ getService }) {
|
||||||
const lifecycle = getService('lifecycle');
|
const lifecycle = getService('lifecycle');
|
||||||
const config = getService('config');
|
const config = getService('config');
|
||||||
const log = getService('log');
|
const log = getService('log');
|
||||||
|
const possibleBrowsers = ['chrome', 'firefox'];
|
||||||
|
const browserType = process.env.TEST_BROWSER_TYPE || 'chrome';
|
||||||
|
|
||||||
const chromedriverApi = await ChromedriverApi.factory(log, config.get('chromedriver.url'));
|
if (!possibleBrowsers.includes(browserType)) {
|
||||||
lifecycle.on('cleanup', async () => await chromedriverApi.stop());
|
throw new Error(`Unexpected TEST_BROWSER_TYPE "${browserType}". Valid options are ` + possibleBrowsers.join(','));
|
||||||
|
}
|
||||||
|
|
||||||
await chromedriverApi.start();
|
const browserDriverApi = await BrowserDriverApi.factory(log, config.get(browserType + 'driver.url'), browserType);
|
||||||
|
lifecycle.on('cleanup', async () => await browserDriverApi.stop());
|
||||||
|
|
||||||
const { command } = await initLeadfootCommand({ log, chromedriverApi });
|
await browserDriverApi.start();
|
||||||
|
|
||||||
|
const { command } = await initLeadfootCommand({ log, browserDriverApi: browserDriverApi });
|
||||||
const interceptors = createRemoteInterceptors(command);
|
const interceptors = createRemoteInterceptors(command);
|
||||||
|
|
||||||
log.info('Remote initialized');
|
log.info('Remote initialized');
|
||||||
|
|
92
yarn.lock
92
yarn.lock
|
@ -246,6 +246,10 @@ address@^1.0.1:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9"
|
resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9"
|
||||||
|
|
||||||
|
adm-zip@0.4.7:
|
||||||
|
version "0.4.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.7.tgz#8606c2cbf1c426ce8c8ec00174447fd49b6eafc1"
|
||||||
|
|
||||||
after@0.8.2:
|
after@0.8.2:
|
||||||
version "0.8.2"
|
version "0.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
|
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
|
||||||
|
@ -1460,6 +1464,10 @@ bluebird@2.9.34:
|
||||||
version "2.9.34"
|
version "2.9.34"
|
||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.9.34.tgz#2f7b4ec80216328a9fddebdf69c8d4942feff7d8"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.9.34.tgz#2f7b4ec80216328a9fddebdf69c8d4942feff7d8"
|
||||||
|
|
||||||
|
bluebird@3.4.6:
|
||||||
|
version "3.4.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f"
|
||||||
|
|
||||||
bluebird@3.5.1, bluebird@^3.3.0:
|
bluebird@3.5.1, bluebird@^3.3.0:
|
||||||
version "3.5.1"
|
version "3.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
|
||||||
|
@ -2025,6 +2033,10 @@ chokidar@^1.4.1, chokidar@^1.6.0, chokidar@^1.7.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "^1.0.0"
|
fsevents "^1.0.0"
|
||||||
|
|
||||||
|
chownr@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
|
||||||
|
|
||||||
chromedriver@2.33.2:
|
chromedriver@2.33.2:
|
||||||
version "2.33.2"
|
version "2.33.2"
|
||||||
resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.33.2.tgz#8fc779d54b6e45bef55d264a1eceed52427a9b49"
|
resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.33.2.tgz#8fc779d54b6e45bef55d264a1eceed52427a9b49"
|
||||||
|
@ -2493,7 +2505,7 @@ create-ecdh@^4.0.0:
|
||||||
bn.js "^4.1.0"
|
bn.js "^4.1.0"
|
||||||
elliptic "^6.0.0"
|
elliptic "^6.0.0"
|
||||||
|
|
||||||
create-error-class@^3.0.0:
|
create-error-class@^3.0.0, create-error-class@^3.0.1:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
|
resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3277,6 +3289,12 @@ dtrace-provider@~0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
nan "^2.0.8"
|
nan "^2.0.8"
|
||||||
|
|
||||||
|
duplexer2@^0.1.4:
|
||||||
|
version "0.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
|
||||||
|
dependencies:
|
||||||
|
readable-stream "^2.0.2"
|
||||||
|
|
||||||
duplexer3@^0.1.4:
|
duplexer3@^0.1.4:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
|
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
|
||||||
|
@ -4516,6 +4534,15 @@ gauge@~2.7.3:
|
||||||
strip-ansi "^3.0.1"
|
strip-ansi "^3.0.1"
|
||||||
wide-align "^1.1.0"
|
wide-align "^1.1.0"
|
||||||
|
|
||||||
|
geckodriver@1.10.0:
|
||||||
|
version "1.10.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.10.0.tgz#73e2f785666521d0d3a9ddc9fd5a0a5e3bf47845"
|
||||||
|
dependencies:
|
||||||
|
adm-zip "0.4.7"
|
||||||
|
bluebird "3.4.6"
|
||||||
|
got "5.6.0"
|
||||||
|
tar "4.0.2"
|
||||||
|
|
||||||
generate-function@^2.0.0:
|
generate-function@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
|
resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
|
||||||
|
@ -4753,6 +4780,27 @@ good-squeeze@2.1.0:
|
||||||
hoek "2.x.x"
|
hoek "2.x.x"
|
||||||
json-stringify-safe "5.0.x"
|
json-stringify-safe "5.0.x"
|
||||||
|
|
||||||
|
got@5.6.0:
|
||||||
|
version "5.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/got/-/got-5.6.0.tgz#bb1d7ee163b78082bbc8eb836f3f395004ea6fbf"
|
||||||
|
dependencies:
|
||||||
|
create-error-class "^3.0.1"
|
||||||
|
duplexer2 "^0.1.4"
|
||||||
|
is-plain-obj "^1.0.0"
|
||||||
|
is-redirect "^1.0.0"
|
||||||
|
is-retry-allowed "^1.0.0"
|
||||||
|
is-stream "^1.0.0"
|
||||||
|
lowercase-keys "^1.0.0"
|
||||||
|
node-status-codes "^1.0.0"
|
||||||
|
object-assign "^4.0.1"
|
||||||
|
parse-json "^2.1.0"
|
||||||
|
pinkie-promise "^2.0.0"
|
||||||
|
read-all-stream "^3.0.0"
|
||||||
|
readable-stream "^2.0.5"
|
||||||
|
timed-out "^2.0.0"
|
||||||
|
unzip-response "^1.0.0"
|
||||||
|
url-parse-lax "^1.0.0"
|
||||||
|
|
||||||
got@^3.2.0:
|
got@^3.2.0:
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/got/-/got-3.3.1.tgz#e5d0ed4af55fc3eef4d56007769d98192bcb2eca"
|
resolved "https://registry.yarnpkg.com/got/-/got-3.3.1.tgz#e5d0ed4af55fc3eef4d56007769d98192bcb2eca"
|
||||||
|
@ -6818,9 +6866,9 @@ lcid@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
invert-kv "^1.0.0"
|
invert-kv "^1.0.0"
|
||||||
|
|
||||||
leadfoot@1.7.1:
|
leadfoot@silne30/leadfoot#validation_for_response_in_ff58:
|
||||||
version "1.7.1"
|
version "1.7.4"
|
||||||
resolved "https://registry.yarnpkg.com/leadfoot/-/leadfoot-1.7.1.tgz#7dae9961f01c9bec862b621ccece0826c8c64599"
|
resolved "https://codeload.github.com/silne30/leadfoot/tar.gz/460c8ed67c08177adc9c79243ff045880f4cad09"
|
||||||
dependencies:
|
dependencies:
|
||||||
dojo "2.0.0-alpha.7"
|
dojo "2.0.0-alpha.7"
|
||||||
jszip "2.5.0"
|
jszip "2.5.0"
|
||||||
|
@ -7580,6 +7628,18 @@ minimost@^1.0.0:
|
||||||
camelcase-keys "^4.0.0"
|
camelcase-keys "^4.0.0"
|
||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
|
|
||||||
|
minipass@^2.2.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.2.1.tgz#5ada97538b1027b4cf7213432428578cb564011f"
|
||||||
|
dependencies:
|
||||||
|
yallist "^3.0.0"
|
||||||
|
|
||||||
|
minizlib@^1.0.4:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb"
|
||||||
|
dependencies:
|
||||||
|
minipass "^2.2.1"
|
||||||
|
|
||||||
mkdirp@0.5.0:
|
mkdirp@0.5.0:
|
||||||
version "0.5.0"
|
version "0.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12"
|
||||||
|
@ -7838,6 +7898,10 @@ node-pre-gyp@^0.6.39:
|
||||||
tar "^2.2.1"
|
tar "^2.2.1"
|
||||||
tar-pack "^3.4.0"
|
tar-pack "^3.4.0"
|
||||||
|
|
||||||
|
node-status-codes@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f"
|
||||||
|
|
||||||
node-uuid@~1.4.0:
|
node-uuid@~1.4.0:
|
||||||
version "1.4.8"
|
version "1.4.8"
|
||||||
resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907"
|
resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907"
|
||||||
|
@ -8238,7 +8302,7 @@ parse-headers@^2.0.0:
|
||||||
for-each "^0.3.2"
|
for-each "^0.3.2"
|
||||||
trim "0.0.1"
|
trim "0.0.1"
|
||||||
|
|
||||||
parse-json@^2.2.0:
|
parse-json@^2.1.0, parse-json@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
|
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -10598,6 +10662,16 @@ tar@2.2.0:
|
||||||
fstream "^1.0.2"
|
fstream "^1.0.2"
|
||||||
inherits "2"
|
inherits "2"
|
||||||
|
|
||||||
|
tar@4.0.2:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/tar/-/tar-4.0.2.tgz#e8e22bf3eec330e5c616d415a698395e294e8fad"
|
||||||
|
dependencies:
|
||||||
|
chownr "^1.0.1"
|
||||||
|
minipass "^2.2.1"
|
||||||
|
minizlib "^1.0.4"
|
||||||
|
mkdirp "^0.5.0"
|
||||||
|
yallist "^3.0.2"
|
||||||
|
|
||||||
tar@^2.2.1, "tar@~2.2.1 ":
|
tar@^2.2.1, "tar@~2.2.1 ":
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
|
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
|
||||||
|
@ -11038,6 +11112,10 @@ unpipe@1.0.0, unpipe@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||||
|
|
||||||
|
unzip-response@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe"
|
||||||
|
|
||||||
unzip-response@^2.0.1:
|
unzip-response@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97"
|
resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97"
|
||||||
|
@ -11822,6 +11900,10 @@ yallist@^2.0.0, yallist@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
|
||||||
|
|
||||||
|
yallist@^3.0.0, yallist@^3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"
|
||||||
|
|
||||||
yargs-parser@^7.0.0:
|
yargs-parser@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue