diff --git a/package.json b/package.json index ae6e3981678a0..716b7356ff260 100644 --- a/package.json +++ b/package.json @@ -333,7 +333,7 @@ "@types/redux-actions": "^2.2.1", "@types/request": "^2.48.2", "@types/rimraf": "^2.0.2", - "@types/selenium-webdriver": "^3.0.16", + "@types/selenium-webdriver": "^4.0.3", "@types/semver": "^5.5.0", "@types/sinon": "^7.0.0", "@types/strip-ansi": "^3.0.0", @@ -429,7 +429,7 @@ "proxyquire": "1.8.0", "regenerate": "^1.4.0", "sass-lint": "^1.12.1", - "selenium-webdriver": "^4.0.0-alpha.4", + "selenium-webdriver": "^4.0.0-alpha.5", "simple-git": "1.116.0", "sinon": "^7.2.2", "strip-ansi": "^3.0.1", diff --git a/test/functional/services/browser.ts b/test/functional/services/browser.ts index ccd32590e941c..a128b354da753 100644 --- a/test/functional/services/browser.ts +++ b/test/functional/services/browser.ts @@ -18,7 +18,9 @@ */ import { cloneDeep } from 'lodash'; -import { IKey, logging } from 'selenium-webdriver'; +import { logging, Key, Origin } from 'selenium-webdriver'; +// @ts-ignore internal modules are not typed +import { LegacyActionSequence } from 'selenium-webdriver/lib/actions'; import { takeUntil } from 'rxjs/operators'; import { modifyUrl } from '../../../src/core/utils'; @@ -31,9 +33,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { const log = getService('log'); const config = getService('config'); const lifecycle = getService('lifecycle'); - const { driver, Key, LegacyActionSequence, browserType } = await getService( - '__webdriver__' - ).init(); + const { driver, browserType } = await getService('__webdriver__').init(); const isW3CEnabled = (driver as any).executor_.w3c === true; @@ -56,7 +56,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { /** * Keyboard events */ - public readonly keys: IKey = Key; + public readonly keys = Key; /** * Browser name @@ -76,10 +76,8 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * Returns instance of Actions API based on driver w3c flag * https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/webdriver_exports_WebDriver.html#actions */ - public getActions(): any { - return this.isW3CEnabled - ? (driver as any).actions() - : (driver as any).actions({ bridge: true }); + public getActions() { + return this.isW3CEnabled ? driver.actions() : driver.actions({ bridge: true }); } /** @@ -101,7 +99,10 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * @return {Promise<{height: number, width: number, x: number, y: number}>} */ public async getWindowSize(): Promise<{ height: number; width: number; x: number; y: number }> { - return await (driver.manage().window() as any).getRect(); + return await driver + .manage() + .window() + .getRect(); } /** @@ -112,10 +113,11 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * @param {number} height * @return {Promise} */ - public async setWindowSize(width: number, height: number): Promise; - public async setWindowSize(...args: number[]): Promise; - public async setWindowSize(...args: unknown[]): Promise { - await (driver.manage().window() as any).setRect({ width: args[0], height: args[1] }); + public async setWindowSize(width: number, height: number) { + await driver + .manage() + .window() + .setRect({ width, height }); } /** @@ -124,7 +126,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * * @return {Promise} */ - public async getCurrentUrl(): Promise { + public async getCurrentUrl() { // strip _t=Date query param when url is read const current = await driver.getCurrentUrl(); const currentWithoutTime = modifyUrl(current, parsed => { @@ -142,7 +144,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * @param {boolean} insertTimestamp Optional * @return {Promise} */ - public async get(url: string, insertTimestamp: boolean = true): Promise { + public async get(url: string, insertTimestamp: boolean = true) { if (insertTimestamp) { const urlWithTime = modifyUrl(url, parsed => { (parsed.query as any)._t = Date.now(); @@ -168,12 +170,12 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { .move({ x: 0, y: 0 }) .perform(); await this.getActions() - .move({ x: point.x, y: point.y, origin: 'pointer' }) + .move({ x: point.x, y: point.y, origin: Origin.POINTER }) .perform(); } else { await this.getActions() .pause(this.getActions().mouse) - .move({ x: point.x, y: point.y, origin: 'pointer' }) + .move({ x: point.x, y: point.y, origin: Origin.POINTER }) .perform(); } } @@ -198,7 +200,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { } return data.location instanceof WebElementWrapper ? { x: data.offset.x || 0, y: data.offset.y || 0, origin: data.location._webElement } - : { x: data.location.x, y: data.location.y, origin: 'pointer' }; + : { x: data.location.x, y: data.location.y, origin: Origin.POINTER }; }; const startPoint = getW3CPoint(from); @@ -223,7 +225,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { return await this.getActions() .move({ origin: from.location._webElement }) .press() - .move({ x: to.location.x, y: to.location.y, origin: 'pointer' }) + .move({ x: to.location.x, y: to.location.y, origin: Origin.POINTER }) .release() .perform(); } else { @@ -243,7 +245,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * * @return {Promise} */ - public async refresh(): Promise { + public async refresh() { await driver.navigate().refresh(); } @@ -253,10 +255,18 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * * @return {Promise} */ - public async goBack(): Promise { + public async goBack() { await driver.navigate().back(); } + /** + * Moves forwards in the browser history. + * https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/webdriver_exports_Navigation.html#forward + */ + public async goForward() { + await driver.navigate().forward(); + } + /** * Sends a sequance of keyboard keys. For each key, this will record a pair of keyDown and keyUp actions * https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/input_exports_Actions.html#sendKeys @@ -282,19 +292,19 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * @param {x: number, y: number} point on browser page * @return {Promise} */ - public async clickMouseButton(point: { x: number; y: number }): Promise { + public async clickMouseButton(point: { x: number; y: number }) { if (this.isW3CEnabled) { await this.getActions() .move({ x: 0, y: 0 }) .perform(); await this.getActions() - .move({ x: point.x, y: point.y, origin: 'pointer' }) + .move({ x: point.x, y: point.y, origin: Origin.POINTER }) .click() .perform(); } else { await this.getActions() .pause(this.getActions().mouse) - .move({ x: point.x, y: point.y, origin: 'pointer' }) + .move({ x: point.x, y: point.y, origin: Origin.POINTER }) .click() .perform(); } @@ -307,7 +317,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * * @return {Promise} */ - public async getPageSource(): Promise { + public async getPageSource() { return await driver.getPageSource(); } @@ -317,7 +327,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * * @return {Promise} */ - public async takeScreenshot(): Promise { + public async takeScreenshot() { return await driver.takeScreenshot(); } @@ -327,7 +337,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * @param {WebElementWrapper} element * @return {Promise} */ - public async doubleClick(): Promise { + public async doubleClick() { await this.getActions() .doubleClick() .perform(); @@ -341,10 +351,8 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * @param {string} handle * @return {Promise} */ - public async switchToWindow(handle: string): Promise; - public async switchToWindow(...args: string[]): Promise; - public async switchToWindow(...args: string[]): Promise { - await (driver.switchTo() as any).window(...args); + public async switchToWindow(nameOrHandle: string) { + await driver.switchTo().window(nameOrHandle); } /** @@ -353,7 +361,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * * @return {Promise} */ - public async getAllWindowHandles(): Promise { + public async getAllWindowHandles() { return await driver.getAllWindowHandles(); } @@ -379,7 +387,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { * * @return {Promise} */ - public async closeCurrentWindow(): Promise { + public async closeCurrentWindow() { await driver.close(); } @@ -418,18 +426,18 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { ); } - public async getScrollTop(): Promise { + public async getScrollTop() { const scrollSize = await driver.executeScript('return document.body.scrollTop'); return parseInt(scrollSize, 10); } - public async getScrollLeft(): Promise { + public async getScrollLeft() { const scrollSize = await driver.executeScript('return document.body.scrollLeft'); return parseInt(scrollSize, 10); } // return promise with REAL scroll position - public async setScrollTop(scrollSize: number | string): Promise { + public async setScrollTop(scrollSize: number | string) { await driver.executeScript('document.body.scrollTop = ' + scrollSize); return this.getScrollTop(); } diff --git a/test/functional/services/find.ts b/test/functional/services/find.ts index 29713304cd5cb..84d19096efedd 100644 --- a/test/functional/services/find.ts +++ b/test/functional/services/find.ts @@ -141,7 +141,7 @@ export async function FindProvider({ getService }: FtrProviderContext) { elements = []; } // Force isStale checks for all the retrieved elements. - await Promise.all(elements.map(async (element: any) => await element.isEnabled())); + await Promise.all(elements.map(async element => await element.isEnabled())); await this._withTimeout(defaultFindTimeout); return elements; }); @@ -322,7 +322,7 @@ export async function FindProvider({ getService }: FtrProviderContext) { log.debug(`Find.clickByPartialLinkText('${linkText}') with timeout=${timeout}`); await retry.try(async () => { const element = await this.byPartialLinkText(linkText, timeout); - await (element as any).moveMouseTo(); + await element.moveMouseTo(); await element.click(); }); } @@ -334,7 +334,7 @@ export async function FindProvider({ getService }: FtrProviderContext) { log.debug(`Find.clickByLinkText('${linkText}') with timeout=${timeout}`); await retry.try(async () => { const element = await this.byLinkText(linkText, timeout); - await (element as any).moveMouseTo(); + await element.moveMouseTo(); await element.click(); }); } @@ -470,7 +470,7 @@ export async function FindProvider({ getService }: FtrProviderContext) { private async _withTimeout(timeout: number) { if (timeout !== this.currentWait) { this.currentWait = timeout; - await (driver.manage() as any).setTimeouts({ implicit: timeout }); + await driver.manage().setTimeouts({ implicit: timeout }); } } } diff --git a/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts b/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts index 65478c4e5ccd2..a2b2f6219745a 100644 --- a/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts +++ b/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts @@ -18,7 +18,7 @@ */ import { delay } from 'bluebird'; -import { WebElement, WebDriver, By, IKey, until } from 'selenium-webdriver'; +import { WebElement, WebDriver, By, Key, until } from 'selenium-webdriver'; // @ts-ignore not supported yet import { PNG } from 'pngjs'; // @ts-ignore not supported yet @@ -33,9 +33,7 @@ import { Browsers } from '../../remote/browsers'; interface Driver { driver: WebDriver; By: typeof By; - Key: IKey; until: typeof until; - LegacyActionSequence: any; } interface TypeOptions { @@ -54,10 +52,9 @@ const RETRY_CLICK_RETRY_ON_ERRORS = [ ]; export class WebElementWrapper { - private By: typeof By = this.webDriver.By; - private Keys: IKey = this.webDriver.Key; + private By = this.webDriver.By; private driver: WebDriver = this.webDriver.driver; - public LegacyAction: any = this.webDriver.LegacyActionSequence; + private Keys = Key; public isW3CEnabled: boolean = (this.webDriver.driver as any).executor_.w3c === true; public static create( @@ -99,11 +96,11 @@ export class WebElementWrapper { timeout?: number ) { if (timeout && timeout !== this.timeout) { - await (this.driver.manage() as any).setTimeouts({ implicit: timeout }); + await this.driver.manage().setTimeouts({ implicit: timeout }); } const elements = await findFunction(); if (timeout && timeout !== this.timeout) { - await (this.driver.manage() as any).setTimeouts({ implicit: this.timeout }); + await this.driver.manage().setTimeouts({ implicit: this.timeout }); } return elements; } @@ -150,10 +147,8 @@ export class WebElementWrapper { } } - private getActions(): any { - return this.isW3CEnabled - ? (this.driver as any).actions() - : (this.driver as any).actions({ bridge: true }); + private getActions() { + return this.isW3CEnabled ? this.driver.actions() : this.driver.actions({ bridge: true }); } /** @@ -310,7 +305,7 @@ export class WebElementWrapper { * @param {string|string[]} keys * @return {Promise} */ - public async pressKeys(keys: T | T[]): Promise; + public async pressKeys(keys: T | T[]): Promise; public async pressKeys(keys: T | T[]): Promise; public async pressKeys(keys: string): Promise { await this.retryCall(async function pressKeys(wrapper) { @@ -391,7 +386,7 @@ export class WebElementWrapper { */ public async getPosition(): Promise<{ height: number; width: number; x: number; y: number }> { return await this.retryCall(async function getPosition(wrapper) { - return await (wrapper._webElement as any).getRect(); + return await wrapper._webElement.getRect(); }); } @@ -404,7 +399,7 @@ export class WebElementWrapper { */ public async getSize(): Promise<{ height: number; width: number; x: number; y: number }> { return await this.retryCall(async function getSize(wrapper) { - return await (wrapper._webElement as any).getRect(); + return await wrapper._webElement.getRect(); }); } @@ -444,7 +439,7 @@ export class WebElementWrapper { * @param { xOffset: 0, yOffset: 0 } options Optional * @return {Promise} */ - public async clickMouseButton(options = { xOffset: 0, yOffset: 0 }): Promise { + public async clickMouseButton(options = { xOffset: 0, yOffset: 0 }) { await this.retryCall(async function clickMouseButton(wrapper) { await wrapper.scrollIntoViewIfNecessary(); if (wrapper.isW3CEnabled) { @@ -474,7 +469,7 @@ export class WebElementWrapper { * @param {WebElementWrapper} element * @return {Promise} */ - public async doubleClick(): Promise { + public async doubleClick() { await this.retryCall(async function clickMouseButton(wrapper) { await wrapper.scrollIntoViewIfNecessary(); await wrapper @@ -680,7 +675,7 @@ export class WebElementWrapper { * @return {Promise} */ public async waitForDeletedByCssSelector(selector: string): Promise { - await (this.driver.manage() as any).setTimeouts({ implicit: 1000 }); + await this.driver.manage().setTimeouts({ implicit: 1000 }); await this.driver.wait( async () => { const found = await this._webElement.findElements(this.By.css(selector)); @@ -689,7 +684,7 @@ export class WebElementWrapper { this.timeout, `The element with ${selector} selector was still present after ${this.timeout} sec.` ); - await (this.driver.manage() as any).setTimeouts({ implicit: this.timeout }); + await this.driver.manage().setTimeouts({ implicit: this.timeout }); } /** @@ -743,9 +738,9 @@ export class WebElementWrapper { * * @returns {Promise} */ - public async takeScreenshot(): Promise { + public async takeScreenshot(): Promise { const screenshot = await this.driver.takeScreenshot(); - const buffer = Buffer.from(screenshot.toString(), 'base64'); + const buffer = Buffer.from(screenshot, 'base64'); const { width, height, x, y } = await this.getPosition(); const windowWidth: number = await this.driver.executeScript( 'return window.document.body.clientWidth' @@ -757,11 +752,12 @@ export class WebElementWrapper { src.height = src.height / 2; let h = false; let v = false; - src.data = src.data.filter((d: any, i: number) => { + const filteredData = src.data.filter((d: any, i: number) => { h = i % 4 ? h : !h; v = i % (src.width * 2 * 4) ? v : !v; return h && v; }); + src.data = Buffer.from(filteredData); } const dst = new PNG({ width, height }); PNG.bitblt(src, dst, x, y, width, height, 0, 0); diff --git a/test/functional/services/remote/remote.ts b/test/functional/services/remote/remote.ts index bbfe929187036..30e6a55c79627 100644 --- a/test/functional/services/remote/remote.ts +++ b/test/functional/services/remote/remote.ts @@ -27,7 +27,7 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { const config = getService('config'); const browserType: Browsers = config.get('browser.type'); - const { driver, By, Key, until, LegacyActionSequence } = await initWebDriver(log, browserType); + const { driver, By, until } = await initWebDriver(log, browserType); const isW3CEnabled = (driver as any).executor_.w3c; const caps = await driver.getCapabilities(); @@ -44,24 +44,35 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { 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() as any).setRect({ width: 1600, height: 1000 }); + await driver + .manage() + .window() + .setRect({ width: 1600, height: 1000 }); }); const windowSizeStack: Array<{ width: number; height: number }> = []; lifecycle.on('beforeTestSuite', async () => { - windowSizeStack.unshift(await (driver.manage().window() as any).getRect()); + windowSizeStack.unshift( + await driver + .manage() + .window() + .getRect() + ); }); lifecycle.on('beforeEachTest', async () => { - await (driver.manage() as any).setTimeouts({ implicit: config.get('timeouts.find') }); + await driver.manage().setTimeouts({ implicit: config.get('timeouts.find') }); }); lifecycle.on('afterTestSuite', async () => { const { width, height } = windowSizeStack.shift()!; - await (driver.manage().window() as any).setRect({ width, height }); + await driver + .manage() + .window() + .setRect({ width, height }); }); lifecycle.on('cleanup', async () => await driver.quit()); - return { driver, By, Key, until, LegacyActionSequence, browserType }; + return { driver, By, until, browserType }; } diff --git a/test/functional/services/remote/webdriver.ts b/test/functional/services/remote/webdriver.ts index 6377d97dad28b..0dc8cf34a041f 100644 --- a/test/functional/services/remote/webdriver.ts +++ b/test/functional/services/remote/webdriver.ts @@ -22,14 +22,10 @@ import { delay } from 'bluebird'; import chromeDriver from 'chromedriver'; // @ts-ignore types not available import geckoDriver from 'geckodriver'; -import { Builder, Capabilities, By, Key, logging, until } from 'selenium-webdriver'; -// @ts-ignore types not available +import { Builder, Capabilities, By, logging, until } from 'selenium-webdriver'; 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'; @@ -93,7 +89,7 @@ async function attemptToCreateCommand(log: ToolingLog, browserType: Browsers) { const firefoxOptions = new firefox.Options(); if (headlessBrowser === '1') { // See: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode - firefoxOptions.addArguments('-headless'); + firefoxOptions.headless(); } return new Builder() .forBrowser(browserType) @@ -123,7 +119,7 @@ async function attemptToCreateCommand(log: ToolingLog, browserType: Browsers) { return; } // abort - return { driver: session, By, Key, until, LegacyActionSequence }; + return { driver: session, By, until }; } export async function initWebDriver(log: ToolingLog, browserType: Browsers) { diff --git a/x-pack/test/functional/apps/code/history.ts b/x-pack/test/functional/apps/code/history.ts index 7275140222552..f1026da2e701d 100644 --- a/x-pack/test/functional/apps/code/history.ts +++ b/x-pack/test/functional/apps/code/history.ts @@ -31,7 +31,6 @@ export default function manageRepositoriesFunctionalTests({ const repositoryListSelector = 'codeRepositoryList > codeRepositoryItem'; describe('browser history can go back while exploring code app', () => { - let driver: any; before(async () => { // Navigate to the code app. await PageObjects.common.navigateToApp('code'); @@ -44,9 +43,6 @@ export default function manageRepositoriesFunctionalTests({ ); // Click the import repository button. await PageObjects.code.clickImportRepositoryButton(); - - const webDriver = await getService('__webdriver__').init(); - driver = webDriver.driver; }); // after(async () => await esArchiver.unload('code')); @@ -101,7 +97,7 @@ export default function manageRepositoriesFunctionalTests({ }); // can go forward to source view page - await driver.navigate().forward(); + await browser.goForward(); await retry.try(async () => { expect(await testSubjects.exists('codeStructureTreeTab')).to.be(true); @@ -124,7 +120,7 @@ export default function manageRepositoriesFunctionalTests({ expect(await testSubjects.exists('codeStructureTreeTab')).to.be(true); }); - await driver.navigate().forward(); + await browser.goForward(); await retry.try(async () => { const searchResultListSelector = 'codeSearchResultList codeSearchResultFileItem'; @@ -169,7 +165,7 @@ export default function manageRepositoriesFunctionalTests({ expect(lang.indexOf('typescript')).to.equal(0); }); - await driver.navigate().forward(); + await browser.goForward(); await retry.try(async () => { const filter = await (await find.allByCssSelector( @@ -219,7 +215,7 @@ export default function manageRepositoriesFunctionalTests({ expect(existence).to.be(false); }); - await driver.navigate().forward(); + await browser.goForward(); await retry.try(async () => { const existence = await find.existsByCssSelector('.code-line-number-21', FIND_TIME); @@ -251,7 +247,7 @@ export default function manageRepositoriesFunctionalTests({ expect(testSubjects.exists('codeFileTreeTabActive')).to.be.ok(); }); - await driver.navigate().forward(); + await browser.goForward(); await retry.try(async () => { // if structure tree tab is active, file tree tab's `data-test-subj` would be `codeFileTreeTab` diff --git a/yarn.lock b/yarn.lock index a94e01b1a8a66..35428a5bc4c5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4013,10 +4013,10 @@ "@types/glob" "*" "@types/node" "*" -"@types/selenium-webdriver@^3.0.16": - version "3.0.16" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-3.0.16.tgz#50a4755f8e33edacd9c406729e9b930d2451902a" - integrity sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA== +"@types/selenium-webdriver@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.0.3.tgz#388f12c464cc1fff5d4c84cb372f19b9ab9b5c81" + integrity sha512-aMKIG1IKwV9/gjhm9uICjvmy4s2SL/bF9fE2WEgLhfdrTLKSIsDMt9M2pTqhZlxllgQPa+EUddtkx4YFTSjadw== "@types/semver@^5.5.0": version "5.5.0" @@ -25267,10 +25267,10 @@ select@^1.1.2: resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= -selenium-webdriver@^4.0.0-alpha.4: - version "4.0.0-alpha.4" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.4.tgz#73694490e02c941d9d0bf7a36f7c49beb9372512" - integrity sha512-etJt20d8qInkxMAHIm5SEpPBSS+CdxVcybnxzSIB/GlWErb8pIWrArz/VA6VfUW0/6tIcokepXQ5ufvdzqqk1A== +selenium-webdriver@^4.0.0-alpha.5: + version "4.0.0-alpha.5" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.5.tgz#e4683b3dbf827d70df09a7e43bf02ebad20fa7c1" + integrity sha512-hktl3DSrhzM59yLhWzDGHIX9o56DvA+cVK7Dw6FcJR6qQ4CGzkaHeXQPcdrslkWMTeq0Ci9AmCxq0EMOvm2Rkg== dependencies: jszip "^3.1.5" rimraf "^2.6.3"