-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add latest webdriverIO runner (#207)
- Loading branch information
Showing
6 changed files
with
491 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "@best/runner-webdriverio", | ||
"license": "MIT", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"version": "4.0.0-alpha8", | ||
"description": "Best Runner (WebdriverIO)", | ||
"keywords": [ | ||
"Best", | ||
"Runner", | ||
"performance" | ||
], | ||
"main": "build/index.js", | ||
"dependencies": { | ||
"@best/runner-abstract": "4.0.0-alpha8", | ||
"@best/types": "4.0.0-alpha8", | ||
"deepmerge": "^4.0.0", | ||
"webdriverio": "^5.13.2" | ||
}, | ||
"files": [ | ||
"build/**/*.js" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* Copyright (c) 2019, salesforce.com, inc. | ||
* All rights reserved. | ||
* SPDX-License-Identifier: MIT | ||
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT | ||
*/ | ||
|
||
import { RunnerOutputStream } from "@best/console-stream"; | ||
import { FrozenGlobalConfig, FrozenProjectConfig, BenchmarkInfo, BenchmarkRuntimeConfig, BenchmarkResults, BenchmarkResultsState, BenchmarkResultsSnapshot } from '@best/types'; | ||
import AbstractRunner from '@best/runner-abstract'; | ||
import WebdriverBrowser from './webdriver'; | ||
|
||
declare var BEST: any; | ||
const UPDATE_INTERVAL = 300; | ||
|
||
|
||
export default class Runner extends AbstractRunner { | ||
|
||
async run(benchmarkInfo: BenchmarkInfo, projectConfig: FrozenProjectConfig, globalConfig: FrozenGlobalConfig, runnerLogStream: RunnerOutputStream): Promise<BenchmarkResultsSnapshot> { | ||
const { benchmarkEntry } = benchmarkInfo; | ||
const { useHttp } = projectConfig; | ||
|
||
const runtimeOptions = this.getRuntimeOptions(projectConfig); | ||
const state = this.initializeBenchmarkState(); | ||
|
||
const { url, terminate } = await this.initializeServer(benchmarkEntry, useHttp); | ||
const browser = new WebdriverBrowser(url, projectConfig); | ||
|
||
try { | ||
await browser.initialize(); | ||
runnerLogStream.onBenchmarkStart(benchmarkEntry); | ||
|
||
const { results } = await this.runIterations(browser, state, runtimeOptions, runnerLogStream); | ||
const environment = await this.getEnvironment({ version:browser.version() }, projectConfig, globalConfig); | ||
|
||
return { results, environment, benchmarkInfo, projectConfig }; | ||
} catch (e) { | ||
runnerLogStream.onBenchmarkError(benchmarkEntry); | ||
throw e; | ||
} finally { | ||
runnerLogStream.onBenchmarkEnd(benchmarkEntry); | ||
await browser.close(); | ||
terminate(); | ||
} | ||
} | ||
|
||
initializeBenchmarkState(): BenchmarkResultsState { | ||
return { executedTime: 0, executedIterations: 0, results: [] }; | ||
} | ||
|
||
async runIterations(browser: WebdriverBrowser, state: BenchmarkResultsState, runtimeOptions: BenchmarkRuntimeConfig, runnnerLogStream: RunnerOutputStream): Promise<BenchmarkResultsState> { | ||
return runtimeOptions.iterateOnClient | ||
? this.runClientIterations(browser, state, runtimeOptions, runnnerLogStream) | ||
: this.runServerIterations(browser, state, runtimeOptions, runnnerLogStream); | ||
} | ||
|
||
async runClientIterations(browser: WebdriverBrowser, state: BenchmarkResultsState, runtimeOptions: BenchmarkRuntimeConfig, runnerLogStream: RunnerOutputStream): Promise<BenchmarkResultsState> { | ||
// Run an iteration to estimate the time it will take | ||
const testResult = await this.runIteration(browser, { iterations: 1 }); | ||
const estimatedIterationTime = testResult.aggregate; | ||
|
||
const start = Date.now(); | ||
// eslint-disable-next-line lwc/no-set-interval | ||
const intervalId = setInterval(() => { | ||
const executing = Date.now() - start; | ||
state.executedTime = executing; | ||
state.executedIterations = Math.round(executing / estimatedIterationTime); | ||
runnerLogStream.updateBenchmarkProgress(state, runtimeOptions); | ||
}, UPDATE_INTERVAL); | ||
|
||
await browser.reloadPage(); | ||
const { results: [root,] } = await this.runIteration(browser, runtimeOptions); | ||
state.results.push(root); | ||
clearInterval(intervalId); | ||
|
||
return state; | ||
} | ||
|
||
async runServerIterations(browser: WebdriverBrowser, state: BenchmarkResultsState, runtimeOptions: BenchmarkRuntimeConfig, runnnerLogStream: RunnerOutputStream): Promise<BenchmarkResultsState> { | ||
while (state.executedTime < runtimeOptions.maxDuration || state.executedIterations < runtimeOptions.minSampleCount) { | ||
const start = Date.now(); | ||
const { results: [root,] } = await this.runIteration(browser, runtimeOptions); | ||
await browser.reloadPage(); | ||
state.executedTime += Date.now() - start; | ||
state.executedIterations++; | ||
if (root) { | ||
state.results.push(root); | ||
} | ||
runnnerLogStream.updateBenchmarkProgress(state, runtimeOptions); | ||
} | ||
|
||
return state; | ||
} | ||
|
||
async runIteration(browser: WebdriverBrowser, payload: any): Promise<BenchmarkResults> { | ||
return browser.evaluate(async (o: any, done: any) => { | ||
try { | ||
done(await BEST.runBenchmark(o)) | ||
} catch(e) { | ||
throw e; | ||
} | ||
}, payload); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Copyright (c) 2019, salesforce.com, inc. | ||
* All rights reserved. | ||
* SPDX-License-Identifier: MIT | ||
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT | ||
*/ | ||
|
||
import { FrozenProjectConfig } from '@best/types'; | ||
import { remote } from 'webdriverio'; | ||
import merge from 'deepmerge'; | ||
|
||
const DEFAULT_WEBDRIVERIO_OPTIONS = { | ||
capabilities: { | ||
timeouts: { "implicit": 0, "pageLoad": 300000, "script": 120000 }, | ||
browserName: "chrome", | ||
}, | ||
hostname: "localhost", | ||
port: 4444, | ||
logLevel: "silent", | ||
} | ||
|
||
export default class WebdriverBrowser { | ||
pageUrl: string; | ||
projectConfig: FrozenProjectConfig; | ||
browser?: WebdriverIOAsync.BrowserObject; | ||
wdioOpts: any; | ||
|
||
constructor(url: string, projectConfig: FrozenProjectConfig) { | ||
this.pageUrl = url; | ||
this.projectConfig = projectConfig; | ||
this.wdioOpts = Object.assign({}, DEFAULT_WEBDRIVERIO_OPTIONS); | ||
|
||
// restricting what client config can override | ||
if (this.projectConfig.benchmarkRunnerConfig.webdriverOptions) { | ||
this.wdioOpts.capabilities = merge(this.wdioOpts.capabilities, | ||
this.projectConfig.benchmarkRunnerConfig.webdriverOptions.capabilities || {}) | ||
} | ||
} | ||
|
||
/** | ||
* Initialize a new browser session and navigate to pageUrl | ||
*/ | ||
async initialize() { | ||
this.browser = await remote(this.wdioOpts); | ||
await this.browser.url(this.pageUrl); | ||
} | ||
|
||
|
||
async close() { | ||
if (this.browser) { | ||
return await this.browser.closeWindow(); | ||
} | ||
} | ||
|
||
async reloadPage() { | ||
if (this.browser) { | ||
await this.browser.refresh(); | ||
} | ||
} | ||
|
||
async evaluate(fn: (o: any, done: any) => any, payload: any) { | ||
if(this.browser) { | ||
return await this.browser.executeAsync(fn, payload); | ||
} | ||
return null; | ||
} | ||
|
||
version() { | ||
return this.wdioOpts.capabilities ? this.wdioOpts.capabilities.browserVersion : "unknown"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"extends": "../../../tsconfig.settings.json", | ||
"compilerOptions": { | ||
"rootDir": "src", | ||
"outDir": "build" | ||
}, | ||
"references": [ | ||
{ "path": "../runner-abstract" }, | ||
{ "path": "../types" } | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.