From a7e1061badc09810ecd9dc3e42b2c2ea09fb1b20 Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 6 Mar 2019 07:25:59 -0800 Subject: [PATCH] Typescript-ify FTR Remote (#32447) * [ftr] flatten GenericProviderTypes to fix "log" types * [ftr/remote] typscript-ify * remove webdriver types, since they're version 3 and we're using version 4 * simplify initWebDriver() function * keep jest tests in the functional tests as js, mixing jest and mocha types doesn't work --- package.json | 1 + packages/kbn-test/types/ftr.d.ts | 17 +++-- src/functional_test_runner/types.ts | 27 ------- .../services/remote/{index.js => index.ts} | 0 ...lel_calls.js => prevent_parallel_calls.ts} | 52 +++++++------ .../services/remote/{remote.js => remote.ts} | 33 ++++++--- .../services/remote/verbose_remote_logging.js | 56 -------------- .../remote/{webdriver.js => webdriver.ts} | 74 +++++++++++-------- yarn.lock | 50 ++++++------- 9 files changed, 131 insertions(+), 179 deletions(-) delete mode 100644 src/functional_test_runner/types.ts rename test/functional/services/remote/{index.js => index.ts} (100%) rename test/functional/services/remote/{prevent_parallel_calls.js => prevent_parallel_calls.ts} (54%) rename test/functional/services/remote/{remote.js => remote.ts} (68%) delete mode 100644 test/functional/services/remote/verbose_remote_logging.js rename test/functional/services/remote/{webdriver.js => webdriver.ts} (62%) diff --git a/package.json b/package.json index 2b03852980a2f..0a19f7e20cffd 100644 --- a/package.json +++ b/package.json @@ -267,6 +267,7 @@ "@types/bluebird": "^3.1.1", "@types/boom": "^7.2.0", "@types/chance": "^1.0.0", + "@types/chromedriver": "^2.38.0", "@types/classnames": "^2.2.3", "@types/d3": "^3.5.41", "@types/dedent": "^0.7.0", diff --git a/packages/kbn-test/types/ftr.d.ts b/packages/kbn-test/types/ftr.d.ts index 8cc4253120635..4d632047fa663 100644 --- a/packages/kbn-test/types/ftr.d.ts +++ b/packages/kbn-test/types/ftr.d.ts @@ -17,7 +17,8 @@ * under the License. */ -import { DefaultServiceProviders } from '../../../src/functional_test_runner/types'; +import { ToolingLog } from '@kbn/dev-utils'; +import { Config, Lifecycle } from '../../../src/functional_test_runner/lib'; interface AsyncInstance { /** @@ -39,22 +40,23 @@ type MaybeAsyncInstance = T extends Promise ? AsyncInstance & X : * Convert a map of providers to a map of the instance types they provide, also converting * promise types into the async instances that other providers will receive. */ -type ProvidedTypeMap = { +type ProvidedTypeMap = { [K in keyof T]: T[K] extends (...args: any[]) => any ? MaybeAsyncInstance> - : never + : unknown }; export interface GenericFtrProviderContext< - ServiceProviders extends object, - PageObjectProviders extends object, - ServiceMap = ProvidedTypeMap, + ServiceProviders extends {}, + PageObjectProviders extends {}, + ServiceMap = ProvidedTypeMap, PageObjectMap = ProvidedTypeMap > { /** * Determine if a service is avaliable * @param serviceName */ + hasService(serviceName: 'config' | 'log' | 'lifecycle'): true; hasService(serviceName: K): serviceName is K; hasService(serviceName: string): serviceName is keyof ServiceMap; @@ -63,6 +65,9 @@ export interface GenericFtrProviderContext< * outside of a test/hook, then make sure to call its `.init()` method and await it's promise. * @param serviceName */ + getService(serviceName: 'config'): Config; + getService(serviceName: 'log'): ToolingLog; + getService(serviceName: 'lifecycle'): Lifecycle; getService(serviceName: T): ServiceMap[T]; /** diff --git a/src/functional_test_runner/types.ts b/src/functional_test_runner/types.ts deleted file mode 100644 index 0d53838b1e16c..0000000000000 --- a/src/functional_test_runner/types.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { ToolingLog } from '@kbn/dev-utils'; -import { Config, Lifecycle } from './lib'; - -export interface DefaultServiceProviders { - config(): Config; - log(): ToolingLog; - lifecycle(): Lifecycle; -} diff --git a/test/functional/services/remote/index.js b/test/functional/services/remote/index.ts similarity index 100% rename from test/functional/services/remote/index.js rename to test/functional/services/remote/index.ts diff --git a/test/functional/services/remote/prevent_parallel_calls.js b/test/functional/services/remote/prevent_parallel_calls.ts similarity index 54% rename from test/functional/services/remote/prevent_parallel_calls.js rename to test/functional/services/remote/prevent_parallel_calls.ts index 511c205093ea3..b2cedcbd5da98 100644 --- a/test/functional/services/remote/prevent_parallel_calls.js +++ b/test/functional/services/remote/prevent_parallel_calls.ts @@ -17,34 +17,44 @@ * under the License. */ -export function preventParallelCalls(fn, filter) { - const execQueue = []; +export function preventParallelCalls( + fn: (this: C, arg: A) => Promise, + filter: (arg: A) => boolean +) { + const execQueue: Task[] = []; - return async function (arg) { - if (filter(arg)) { - return await fn.call(this, arg); + class Task { + public promise: Promise; + private resolve!: (result: R) => void; + private reject!: (error: Error) => void; + + constructor(private readonly context: C, private readonly arg: A) { + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); } - const task = { - exec: async () => { - try { - task.resolve(await fn.call(this, arg)); - } catch (error) { - task.reject(error); - } finally { - execQueue.shift(); - if (execQueue.length) { - execQueue[0].exec(); - } + public async exec() { + try { + this.resolve(await fn.call(this.context, this.arg)); + } catch (error) { + this.reject(error); + } finally { + execQueue.shift(); + if (execQueue.length) { + execQueue[0].exec(); } } - }; + } + } - task.promise = new Promise((resolve, reject) => { - task.resolve = resolve; - task.reject = reject; - }); + return async function(this: C, arg: A) { + if (filter(arg)) { + return await fn.call(this, arg); + } + const task = new Task(this, arg); if (execQueue.push(task) === 1) { // only item in the queue, kick it off task.exec(); diff --git a/test/functional/services/remote/remote.js b/test/functional/services/remote/remote.ts similarity index 68% rename from test/functional/services/remote/remote.js rename to test/functional/services/remote/remote.ts index cea5f2b69d3a9..c4cf50b02046b 100644 --- a/test/functional/services/remote/remote.js +++ b/test/functional/services/remote/remote.ts @@ -17,32 +17,42 @@ * under the License. */ +import { FtrProviderContext } from '../../ftr_provider_context'; import { initWebDriver } from './webdriver'; -export async function RemoteProvider({ getService }) { +export async function RemoteProvider({ getService }: FtrProviderContext) { const lifecycle = getService('lifecycle'); const log = getService('log'); const config = getService('config'); - const possibleBrowsers = ['chrome', 'firefox', 'ie']; const browserType = process.env.TEST_BROWSER_TYPE || 'chrome'; - if (!possibleBrowsers.includes(browserType)) { - throw new Error(`Unexpected TEST_BROWSER_TYPE "${browserType}". Valid options are ` + possibleBrowsers.join(',')); + if (browserType !== 'chrome' && browserType !== 'firefox') { + throw new Error( + `Unexpected TEST_BROWSER_TYPE "${browserType}", only "chrome" and "firefox" are supported` + ); } - const { driver, By, Key, until, LegacyActionSequence } = await initWebDriver({ log, browserType }); + const { driver, By, Key, until, LegacyActionSequence } = await initWebDriver(log, browserType); log.info('Remote initialized'); lifecycle.on('beforeTests', async () => { // hard coded default, can be overridden per suite using `browser.setWindowSize()` // and will be automatically reverted after each suite - await driver.manage().window().setRect({ width: 1600, height: 1000 }); + await driver + .manage() + .window() + .setRect({ width: 1600, height: 1000 }); }); - const windowSizeStack = []; + const windowSizeStack: Array<{ width: number; height: number }> = []; lifecycle.on('beforeTestSuite', async () => { - windowSizeStack.unshift(await driver.manage().window().getRect()); + windowSizeStack.unshift( + await driver + .manage() + .window() + .getRect() + ); }); lifecycle.on('beforeEachTest', async () => { @@ -50,8 +60,11 @@ export async function RemoteProvider({ getService }) { }); lifecycle.on('afterTestSuite', async () => { - const { width, height } = windowSizeStack.shift(); - await driver.manage().window().setRect({ width: width, height: height }); + const { width, height } = windowSizeStack.shift()!; + await driver + .manage() + .window() + .setRect({ width, height }); }); lifecycle.on('cleanup', async () => await driver.quit()); diff --git a/test/functional/services/remote/verbose_remote_logging.js b/test/functional/services/remote/verbose_remote_logging.js deleted file mode 100644 index 42ea4f7e00f85..0000000000000 --- a/test/functional/services/remote/verbose_remote_logging.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { green, magentaBright } from 'chalk'; - -export function initVerboseRemoteLogging(log, server) { - const wrap = (original, httpMethod) => (path, requestData, pathParts) => { - const url = '/' + path.split('/').slice(2).join('/').replace(/\$(\d)/, function (_, index) { - return encodeURIComponent(pathParts[index]); - }); - - if (requestData == null) { - log.verbose('[remote] > %s %s', httpMethod, url); - } else { - log.verbose('[remote] > %s %s %j', httpMethod, url, requestData); - } - - return original.call(server, path, requestData, pathParts) - .then(result => { - log.verbose(`[remote] < %s %s ${green('OK')}`, httpMethod, url); - return result; - }) - .catch(error => { - let message; - try { - message = JSON.parse(error.response.data).value.message; - } catch (err) { - message = err.message; - } - - log.verbose(`[remote] < %s %s ${magentaBright('ERR')} %j`, httpMethod, url, message.split(/\r?\n/)[0]); - throw error; - }); - }; - - server._get = wrap(server._get, 'GET'); - server._post = wrap(server._post, 'POST'); - server._delete = wrap(server._delete, 'DELETE'); - return server; -} diff --git a/test/functional/services/remote/webdriver.js b/test/functional/services/remote/webdriver.ts similarity index 62% rename from test/functional/services/remote/webdriver.js rename to test/functional/services/remote/webdriver.ts index 725d98bfbb25f..0be87382c94a0 100644 --- a/test/functional/services/remote/webdriver.js +++ b/test/functional/services/remote/webdriver.ts @@ -17,26 +17,31 @@ * under the License. */ +import { ToolingLog } from '@kbn/dev-utils'; import { delay } from 'bluebird'; -import { Builder, By, Key, until, logging } from 'selenium-webdriver'; -const { LegacyActionSequence } = require('selenium-webdriver/lib/actions'); -const { getLogger } = require('selenium-webdriver/lib/logging'); -const { Executor } = require('selenium-webdriver/lib/http'); -const chrome = require('selenium-webdriver/chrome'); -const firefox = require('selenium-webdriver/firefox'); -const geckoDriver = require('geckodriver'); -const chromeDriver = require('chromedriver'); -const throttleOption = process.env.TEST_THROTTLE_NETWORK; +import chromeDriver from 'chromedriver'; +// @ts-ignore types not available +import geckoDriver from 'geckodriver'; + +// @ts-ignore types for 4.0 not available yet +import { Builder, By, Key, logging, until } from 'selenium-webdriver'; +// @ts-ignore types not available +import chrome from 'selenium-webdriver/chrome'; +// @ts-ignore types not available +import firefox from 'selenium-webdriver/firefox'; +// @ts-ignore internal modules are not typed +import { LegacyActionSequence } from 'selenium-webdriver/lib/actions'; +// @ts-ignore internal modules are not typed +import { Executor } from 'selenium-webdriver/lib/http'; +// @ts-ignore internal modules are not typed +import { getLogger } from 'selenium-webdriver/lib/logging'; import { preventParallelCalls } from './prevent_parallel_calls'; +const throttleOption = process.env.TEST_THROTTLE_NETWORK; const SECOND = 1000; const MINUTE = 60 * SECOND; -const NO_QUEUE_COMMANDS = [ - 'getStatus', - 'newSession', - 'quit' -]; +const NO_QUEUE_COMMANDS = ['getStatus', 'newSession', 'quit']; /** * Best we can tell WebDriver locks up sometimes when we send too many @@ -46,24 +51,26 @@ const NO_QUEUE_COMMANDS = [ * queue all calls to Executor#send() if there is already a call in * progress. */ -Executor.prototype.execute = preventParallelCalls(Executor.prototype.execute, (command) => ( - NO_QUEUE_COMMANDS.includes(command.getName()) -)); +Executor.prototype.execute = preventParallelCalls( + Executor.prototype.execute, + (command: { getName: () => string }) => NO_QUEUE_COMMANDS.includes(command.getName()) +); let attemptCounter = 0; -async function attemptToCreateCommand(log, browserType) { +async function attemptToCreateCommand(log: ToolingLog, browserType: 'chrome' | 'firefox') { const attemptId = ++attemptCounter; log.debug('[webdriver] Creating session'); - const buildDriverInstance = async (browserType) => { + const buildDriverInstance = async () => { switch (browserType) { case 'chrome': const chromeOptions = new chrome.Options(); - const loggingPref = new logging.Preferences().setLevel(logging.Type.BROWSER, logging.Level.ALL); + const loggingPref = new logging.Preferences(); + loggingPref.setLevel(logging.Type.BROWSER, logging.Level.ALL); chromeOptions.setLoggingPrefs(loggingPref); if (process.env.TEST_BROWSER_HEADLESS) { - //Use --disable-gpu to avoid an error from a missing Mesa library, as per - //See: https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md + // Use --disable-gpu to avoid an error from a missing Mesa library, as per + // See: https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md chromeOptions.addArguments('headless', 'disable-gpu'); } return new Builder() @@ -74,7 +81,7 @@ async function attemptToCreateCommand(log, browserType) { case 'firefox': const firefoxOptions = new firefox.Options(); if (process.env.TEST_BROWSER_HEADLESS) { - //See: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode + // See: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode firefoxOptions.addArguments('-headless'); } return new Builder() @@ -87,31 +94,34 @@ async function attemptToCreateCommand(log, browserType) { } }; - const session = await buildDriverInstance(browserType); + const session = await buildDriverInstance(); - if (throttleOption === 'true' && browserType === 'chrome') { //Only chrome supports this option. + if (throttleOption === 'true' && browserType === 'chrome') { + // Only chrome supports this option. log.debug('NETWORK THROTTLED: 768k down, 256k up, 100ms latency.'); + session.setNetworkConditions({ offline: false, latency: 100, // Additional latency (ms). download_throughput: 768 * 1024, // These speeds are in bites per second, not kilobytes. - upload_throughput: 256 * 1024 + upload_throughput: 256 * 1024, }); } - if (attemptId !== attemptCounter) return; // abort + if (attemptId !== attemptCounter) { + return; + } // abort return { driver: session, By, Key, until, LegacyActionSequence }; } -export async function initWebDriver({ log, browserType }) { +export async function initWebDriver(log: ToolingLog, browserType: 'chrome' | 'firefox') { const logger = getLogger('webdriver.http.Executor'); logger.setLevel(logging.Level.FINEST); - logger.addHandler((entry) => { + logger.addHandler((entry: { message: string }) => { log.verbose(entry.message); }); - return await Promise.race([ (async () => { await delay(2 * MINUTE); @@ -122,7 +132,7 @@ export async function initWebDriver({ log, browserType }) { while (true) { const command = await Promise.race([ delay(30 * SECOND), - attemptToCreateCommand(log, browserType) + attemptToCreateCommand(log, browserType), ]); if (!command) { @@ -131,6 +141,6 @@ export async function initWebDriver({ log, browserType }) { return command; } - })() + })(), ]); } diff --git a/yarn.lock b/yarn.lock index d5c87e942fedc..043f85e1982f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1648,6 +1648,13 @@ resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.10.tgz#780d552467824be4a241b29510a7873a7432c4a6" integrity sha512-fOM/Jhv51iyugY7KOBZz2ThfT1gwvsGCfWxpLpZDgkGjpEO4Le9cld07OdskikLjDUQJ43dzDaVRSFwQlpdqVg== +"@types/chromedriver@^2.38.0": + version "2.38.0" + resolved "https://registry.yarnpkg.com/@types/chromedriver/-/chromedriver-2.38.0.tgz#971032b73eb7f44036f4f5bed59a7fd5b468014f" + integrity sha512-vcPGkZt1y2YVXKAY8SwCvU0u9mgw9+7tBV4HGb0YX/6bu1WXbb61bf8Y/N+xNCYwEj/Ug1UAMnhCcsSohXzRXw== + dependencies: + "@types/node" "*" + "@types/classnames@^2.2.3": version "2.2.3" resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.3.tgz#3f0ff6873da793870e20a260cada55982f38a9e5" @@ -7107,11 +7114,6 @@ core-js@^1.0.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= -core-js@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65" - integrity sha1-+rg/uwstjchfpjbEudNMdUIMbWU= - core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -8988,11 +8990,6 @@ es6-promise@^4.0.3, es6-promise@~4.2.4: resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" integrity sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ== -es6-promise@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6" - integrity sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y= - es6-promisify@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" @@ -14524,15 +14521,14 @@ jsx-ast-utils@^2.0.1: array-includes "^3.0.3" jszip@^3.1.3: - version "3.1.5" - resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37" - integrity sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ== + version "3.2.0" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.2.0.tgz#1c179e8692777490ca4e9b8f3ced08f9b820da2c" + integrity sha512-4WjbsaEtBK/DHeDZOPiPw5nzSGLDEDDreFRDEgnoMwmknPjTqa+23XuYFk6NiGbeiAeZCctiQ/X/z0lQBmDVOQ== dependencies: - core-js "~2.3.0" - es6-promise "~3.0.2" - lie "~3.1.0" + lie "~3.3.0" pako "~1.0.2" - readable-stream "~2.0.6" + readable-stream "~2.3.6" + set-immediate-shim "~1.0.1" just-extend@^1.1.27: version "1.1.27" @@ -14893,10 +14889,10 @@ license-checker@^16.0.0: spdx-satisfies "^0.1.3" treeify "^1.0.1" -lie@~3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" - integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4= +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== dependencies: immediate "~3.0.5" @@ -17594,9 +17590,9 @@ pako@^0.2.5: integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU= pako@~1.0.2: - version "1.0.8" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.8.tgz#6844890aab9c635af868ad5fecc62e8acbba3ea4" - integrity sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA== + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== pako@~1.0.5: version "1.0.6" @@ -19644,7 +19640,7 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -19686,7 +19682,7 @@ readable-stream@~1.1.0, readable-stream@~1.1.9: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@~2.0.0, readable-stream@~2.0.6: +readable-stream@~2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" integrity sha1-j5A0HmilPMySh4jaz80Rs265t44= @@ -21042,7 +21038,7 @@ set-getter@^0.1.0: dependencies: to-object-path "^0.3.0" -set-immediate-shim@^1.0.0: +set-immediate-shim@^1.0.0, set-immediate-shim@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=