Skip to content

Commit

Permalink
FTR: add chromium-based Edge browser support (elastic#61684) (elastic…
Browse files Browse the repository at this point in the history
…#63068)

* bump dependency, add edge support in ftr services

* add config files

* fix browser version for msedge

* use npm ms-chromium-edge-driver

* download edge driver aside from session creation

* move dependency to dev

* update dist/index file

* bump edge-driver version

* change type to msedge to match w3c spec

* fix discover tests for Edge

* Revert "fix discover tests for Edge"

This reverts commit 87e7fdd.

* bump driver version up

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
dmlemeshko and elasticmachine committed Apr 9, 2020
1 parent 9aa599c commit e8caa06
Show file tree
Hide file tree
Showing 10 changed files with 412 additions and 44 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@
"@types/recompose": "^0.30.6",
"@types/redux-actions": "^2.6.1",
"@types/request": "^2.48.2",
"@types/selenium-webdriver": "^4.0.5",
"@types/selenium-webdriver": "4.0.9",
"@types/semver": "^5.5.0",
"@types/sinon": "^7.0.13",
"@types/strip-ansi": "^3.0.0",
Expand Down Expand Up @@ -454,6 +454,7 @@
"load-grunt-config": "^3.0.1",
"mocha": "^7.1.1",
"mock-http-server": "1.3.0",
"ms-chromium-edge-driver": "^0.2.0",
"multistream": "^2.1.1",
"murmurhash3js": "3.0.1",
"mutation-observer": "^1.0.3",
Expand All @@ -472,7 +473,7 @@
"react-textarea-autosize": "^7.1.2",
"regenerate": "^1.4.0",
"sass-lint": "^1.12.1",
"selenium-webdriver": "^4.0.0-alpha.5",
"selenium-webdriver": "^4.0.0-alpha.7",
"simple-git": "1.116.0",
"simplebar-react": "^2.1.0",
"sinon": "^7.4.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export const schema = Joi.object()
browser: Joi.object()
.keys({
type: Joi.string()
.valid('chrome', 'firefox', 'ie')
.valid('chrome', 'firefox', 'ie', 'msedge')
.default('chrome'),

logPollingMs: Joi.number().default(100),
Expand Down
34 changes: 34 additions & 0 deletions test/functional/config.edge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.
*/

export default async function({ readConfigFile }) {
const defaultConfig = await readConfigFile(require.resolve('./config'));

return {
...defaultConfig.getAll(),

browser: {
type: 'msedge',
},

junit: {
reportName: 'MS Chromium Edge UI Functional Tests',
},
};
}
4 changes: 3 additions & 1 deletion test/functional/services/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ export async function BrowserProvider({ getService }: FtrProviderContext) {
*/
public readonly browserType: string = browserType;

public readonly isChrome: boolean = browserType === Browsers.Chrome;
public readonly isChromium: boolean = [Browsers.Chrome, Browsers.ChromiumEdge].includes(
browserType
);

public readonly isFirefox: boolean = browserType === Browsers.Firefox;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class WebElementWrapper {
private driver: WebDriver = this.webDriver.driver;
private Keys = Key;
public isW3CEnabled: boolean = (this.webDriver.driver as any).executor_.w3c === true;
public isChromium: boolean = [Browsers.Chrome, Browsers.ChromiumEdge].includes(this.browserType);

public static create(
webElement: WebElement | WebElementWrapper,
Expand All @@ -63,7 +64,7 @@ export class WebElementWrapper {
timeout: number,
fixedHeaderHeight: number,
logger: ToolingLog,
browserType: string
browserType: Browsers
): WebElementWrapper {
if (webElement instanceof WebElementWrapper) {
return webElement;
Expand All @@ -87,7 +88,7 @@ export class WebElementWrapper {
private timeout: number,
private fixedHeaderHeight: number,
private logger: ToolingLog,
private browserType: string
private browserType: Browsers
) {}

private async _findWithCustomTimeout(
Expand Down Expand Up @@ -243,7 +244,7 @@ export class WebElementWrapper {
return this.clearValueWithKeyboard();
}
await this.retryCall(async function clearValue(wrapper) {
if (wrapper.browserType === Browsers.Chrome || options.withJS) {
if (wrapper.isChromium || options.withJS) {
// https://bugs.chromium.org/p/chromedriver/issues/detail?id=2702
await wrapper.driver.executeScript(`arguments[0].value=''`, wrapper._webElement);
} else {
Expand Down Expand Up @@ -275,7 +276,7 @@ export class WebElementWrapper {
await delay(100);
}
} else {
if (this.browserType === Browsers.Chrome) {
if (this.isChromium) {
// https://bugs.chromium.org/p/chromedriver/issues/detail?id=30
await this.retryCall(async function clearValueWithKeyboard(wrapper) {
await wrapper.driver.executeScript(`arguments[0].select();`, wrapper._webElement);
Expand Down
1 change: 1 addition & 0 deletions test/functional/services/remote/browsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export enum Browsers {
Chrome = 'chrome',
Firefox = 'firefox',
InternetExplorer = 'ie',
ChromiumEdge = 'msedge',
}
15 changes: 11 additions & 4 deletions test/functional/services/remote/remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,23 @@ export async function RemoteProvider({ getService }: FtrProviderContext) {
lifecycle,
config.get('browser.logPollingMs')
);

const isW3CEnabled = (driver as any).executor_.w3c;

const caps = await driver.getCapabilities();
const browserVersion = caps.get(isW3CEnabled ? 'browserVersion' : 'version');
const browserVersion = caps.get(
isW3CEnabled || browserType === Browsers.ChromiumEdge ? 'browserVersion' : 'version'
);

log.info(`Remote initialized: ${caps.get('browserName')} ${browserVersion}`);
log.info(
`Remote initialized: ${caps.get(
'browserName'
)} ${browserVersion}, w3c compliance=${isW3CEnabled}`
);

if (browserType === Browsers.Chrome) {
if ([Browsers.Chrome, Browsers.ChromiumEdge].includes(browserType)) {
log.info(
`Chromedriver version: ${caps.get('chrome').chromedriverVersion}, w3c=${isW3CEnabled}`
`${browserType}driver version: ${caps.get(browserType)[`${browserType}driverVersion`]}`
);
}

Expand Down
45 changes: 44 additions & 1 deletion test/functional/services/remote/webdriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ import firefox from 'selenium-webdriver/firefox';
// @ts-ignore types not available
import ie from 'selenium-webdriver/ie';
// @ts-ignore internal modules are not typed
import edge from 'selenium-webdriver/edge';
import { installDriver } from 'ms-chromium-edge-driver';
// @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 { pollForLogEntry$ } from './poll_for_log_entry';
import { createStdoutSocket } from './create_stdout_stream';
import { preventParallelCalls } from './prevent_parallel_calls';
Expand Down Expand Up @@ -65,6 +67,7 @@ Executor.prototype.execute = preventParallelCalls(
);

let attemptCounter = 0;
let edgePaths: { driverPath: string | undefined; browserPath: string | undefined };
async function attemptToCreateCommand(
log: ToolingLog,
browserType: Browsers,
Expand All @@ -76,6 +79,41 @@ async function attemptToCreateCommand(

const buildDriverInstance = async () => {
switch (browserType) {
case 'msedge': {
if (edgePaths && edgePaths.browserPath && edgePaths.driverPath) {
const edgeOptions = new edge.Options();
if (headlessBrowser === '1') {
// @ts-ignore internal modules are not typed
edgeOptions.headless();
}
// @ts-ignore internal modules are not typed
edgeOptions.setEdgeChromium(true);
// @ts-ignore internal modules are not typed
edgeOptions.setBinaryPath(edgePaths.browserPath);
const session = await new Builder()
.forBrowser('MicrosoftEdge')
.setEdgeOptions(edgeOptions)
.setEdgeService(new edge.ServiceBuilder(edgePaths.driverPath))
.build();
return {
session,
consoleLog$: pollForLogEntry$(session, logging.Type.BROWSER, logPollingMs).pipe(
takeUntil(lifecycle.cleanup.after$),
map(({ message, level: { name: level } }) => ({
message: message.replace(/\\n/g, '\n'),
level,
}))
),
};
} else {
throw new Error(
`Chromium Edge session requires browser or driver path to be defined: ${JSON.stringify(
edgePaths
)}`
);
}
}

case 'chrome': {
const chromeCapabilities = Capabilities.chrome();
const chromeOptions = [
Expand Down Expand Up @@ -262,6 +300,11 @@ export async function initWebDriver(
log.verbose(entry.message);
});

// download Edge driver only in case of usage
if (browserType === Browsers.ChromiumEdge) {
edgePaths = await installDriver();
}

return await Promise.race([
(async () => {
await delay(2 * MINUTE);
Expand Down
21 changes: 21 additions & 0 deletions x-pack/test/functional/config.edge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export default async function({ readConfigFile }) {
const chromeConfig = await readConfigFile(require.resolve('./config'));

return {
...chromeConfig.getAll(),

browser: {
type: 'msedge',
},

junit: {
reportName: 'MS Chromium Edge XPack UI Functional Tests',
},
};
}
Loading

0 comments on commit e8caa06

Please sign in to comment.