Skip to content

Commit

Permalink
(@wdio/browser-runner): Further improvements to mocking in browser (#…
Browse files Browse the repository at this point in the history
…10728)

* (@wdio/browser-runner): enable mocking for multiple files/browser in parallel

* update unit tests

* unskip e2e test

* speed up execution, update deps

* fix vue execution

* no new spec edge case

* test with higher timeout

* performance improvements

* fix test

* fix tests on windows

* make it work in vue again

* fix in windows

* try without ?import
  • Loading branch information
christian-bromann committed Jul 14, 2023
1 parent 746504a commit 7623741
Show file tree
Hide file tree
Showing 20 changed files with 1,234 additions and 1,381 deletions.
5 changes: 1 addition & 4 deletions e2e/browser-runner/lit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ describe('Lit Component testing', () => {
expect(namespacedModule).toBe('some value')
})

/**
* fails in CI on MacOS
*/
it.skip('should allow to manual mock namespaces deps', async () => {
it('should allow to manual mock namespaces deps', async () => {
expect(someExport).toBe('foobarloo')
expect(namedExports).toEqual(['PointerEventsCheckLevel', 'default'])
})
Expand Down
2,045 changes: 814 additions & 1,231 deletions e2e/package-lock.json

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
"test:browser:vue": "run-s test:browser:vue:*",
"test:browser:vue:wdio": "cross-env WDIO_PRESET=vue node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec ./browser-runner/vue.test.js",
"test:browser:vue:verifyCoverage": "run-s verifyCoverage",
"_test:browser:svelte": "run-s test:browser:svelte:*",
"_test:browser:svelte:wdio": "cross-env WDIO_PRESET=svelte node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec ./browser-runner/svelte.test.js",
"_test:browser:svelte:verifyCoverage": "run-s verifyCoverage",
"test:browser:svelte": "run-s test:browser:svelte:*",
"test:browser:svelte:wdio": "cross-env WDIO_PRESET=svelte node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec ./browser-runner/svelte.test.js",
"test:browser:svelte:verifyCoverage": "run-s verifyCoverage",
"test:browser:lit": "run-s test:browser:lit:*",
"test:browser:lit:wdio": "cross-env WDIO_PRESET=lit node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec ./browser-runner/lit.test.js",
"test:browser:lit:verifyCoverage": "run-s verifyCoverage",
Expand All @@ -27,28 +27,28 @@
"verifyCoverage": "test -d ./browser-runner/coverage"
},
"devDependencies": {
"@babel/plugin-transform-react-jsx-development": "^7.18.6",
"@babel/plugin-transform-react-jsx-development": "^7.22.5",
"@jspm/core": "^2.0.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/preact": "^3.2.2",
"@testing-library/react": "^13.4.0",
"@testing-library/svelte": "^3.2.2",
"@testing-library/preact": "^3.2.3",
"@testing-library/react": "^14.0.0",
"@testing-library/svelte": "^4.0.3",
"@testing-library/user-event": "^14.4.3",
"@testing-library/vue": "^6.6.1",
"@types/testing-library__jest-dom": "^5.14.5",
"@testing-library/vue": "^7.0.0",
"@types/testing-library__jest-dom": "^5.14.8",
"babel-plugin-transform-hook-names": "^1.0.2",
"cross-env": "^7.0.3",
"expect": "^29.1.2",
"graphql-request": "^5.1.0",
"expect": "^29.6.1",
"graphql-request": "^6.1.0",
"mocha": "^10.2.0",
"wdio-chromedriver-service": "^8.0.1",
"wdio-chromedriver-service": "^8.1.1",
"wdio-safaridriver-service": "^2.1.0"
},
"dependencies": {
"lit": "^2.4.0",
"preact": "^10.11.1",
"lit": "^2.7.6",
"preact": "^10.16.0",
"react": "^18.2.0",
"svelte": "^3.51.0",
"vue": "^3.2.40"
"svelte": "^4.0.5",
"vue": "^3.3.4"
}
}
2 changes: 1 addition & 1 deletion packages/wdio-browser-runner/src/browser/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ declare global {
__wdioEvents__: any[]
__wdioSocket__: WebSocket
__wdioConnectPromise__: Promise<WebSocket>
__wdioMockFactories__: Record<string, any>
__wdioMockCache__: Map<string, any>
}
}

Expand Down
3 changes: 1 addition & 2 deletions packages/wdio-browser-runner/src/browser/spy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const ERROR_MESSAGE = '[wdio] There was an error, when mocking a module. If you
const socket = window.__wdioSocket__
const mockResolver = new Map<string, (value: unknown) => void>()
const origin = window.__wdioSpec__.split('/').slice(0, -1).join('/')
window.__wdioMockFactories__ = []
export async function mock (path: string, factory?: MockFactoryWithHelper) {
/**
* mock calls without factory parameter should get removed from the source code
Expand All @@ -43,7 +42,7 @@ export async function mock (path: string, factory?: MockFactoryWithHelper) {
value: { path: mockPath, origin, namedExports: Object.keys(resolvedMock) }
}))

window.__wdioMockFactories__[mockPath] = resolvedMock
window.__wdioMockCache__.set(mockPath, resolvedMock)
return new Promise((resolve) => mockResolver.set(mockPath, resolve))
} catch (err: unknown) {
throw new Error(ERROR_MESSAGE + '\n' + (err as Error).stack)
Expand Down
44 changes: 25 additions & 19 deletions packages/wdio-browser-runner/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ import type { HookTriggerEvent } from './vite/types.js'
import type { BrowserRunnerOptions as BrowserRunnerOptionsImport, CoverageOptions, MockFactoryWithHelper } from './types.js'

const log = logger('@wdio/browser-runner')
type WorkerMessagePayload = SessionStartedMessage | SessionEndedMessage | WorkerHookResultMessage | WorkerCoverageMapMessage

export default class BrowserRunner extends LocalRunner {
#options: BrowserRunnerOptionsImport
#config: Options.Testrunner
#server: ViteServer
#servers: Set<ViteServer> = new Set()
#coverageOptions: CoverageOptions
#reportsDirectory: string

Expand All @@ -44,7 +47,7 @@ export default class BrowserRunner extends LocalRunner {
throw new Error(FRAMEWORK_SUPPORT_ERROR)
}

this.#server = new ViteServer(options, _config)
this.#options = options
this.#config = _config
this.#coverageOptions = options.coverage || <CoverageOptions>{}
this.#reportsDirectory = this.#coverageOptions.reportsDirectory || path.join(this.#config.rootDir!, DEFAULT_REPORTS_DIRECTORY)
Expand All @@ -64,13 +67,6 @@ export default class BrowserRunner extends LocalRunner {
*/
async initialise() {
log.info('Initiate browser environment')
try {
await this.#server.start()
this._config.baseUrl = `http://localhost:${this.#server.config.server?.port}`
} catch (err: any) {
throw new Error(`Vite server failed to start: ${err.stack}`)
}

if (typeof this.#coverageOptions.clean === 'undefined' || this.#coverageOptions.clean) {
const reportsDirectoryExist = await fs.access(this.#reportsDirectory)
.then(() => true, () => false)
Expand All @@ -82,27 +78,35 @@ export default class BrowserRunner extends LocalRunner {
await super.initialise()
}

run (runArgs: RunArgs): WorkerInstance {
async run (runArgs: RunArgs): Promise<WorkerInstance> {
runArgs.caps = makeHeadless(this.options, runArgs.caps)
const server = new ViteServer(this.#options, this.#config)

if (runArgs.command === 'run') {
try {
await server.start()
runArgs.args.baseUrl = `http://localhost:${server.config.server?.port}`
} catch (err: any) {
throw new Error(`Vite server failed to start: ${err.stack}`)
}

if (!runArgs.args.baseUrl && runArgs.command === 'run') {
runArgs.args.baseUrl = this._config.baseUrl
}

const worker = super.run(runArgs)
this.#server.on('debugState', (state: boolean) => worker.postMessage('switchDebugState', state, true))
this.#server.on('workerHookExecution', (payload: HookTriggerEvent) => {
const worker = await super.run(runArgs)
server.on('debugState', (state: boolean) => worker.postMessage('switchDebugState', state, true))
server.on('workerHookExecution', (payload: HookTriggerEvent) => {
if (worker.cid !== payload.cid) {
return
}
if (worker.isKilled) {
log.debug(`Worker with cid ${payload.cid} was killed, skipping hook execution`)
return process.nextTick(() => this.#server.resolveHook(payload))
return process.nextTick(() => server.resolveHook(payload))
}
return worker.postMessage('workerHookExecution', payload, true)
})

worker.on('message', this.#onWorkerMessage.bind(this))
worker.on('message', (payload: WorkerMessagePayload) => this.#onWorkerMessage(payload, server))
return worker
}

Expand All @@ -113,11 +117,13 @@ export default class BrowserRunner extends LocalRunner {
*/
async shutdown() {
await super.shutdown()
await this.#server.close()
for (const server of this.#servers) {
await server.close()
}
return this._generateCoverageReports()
}

async #onWorkerMessage (payload: SessionStartedMessage | SessionEndedMessage | WorkerHookResultMessage | WorkerCoverageMapMessage) {
async #onWorkerMessage (payload: WorkerMessagePayload, workerServer: ViteServer) {
if (payload.name === 'sessionStarted' && !SESSIONS.has(payload.cid!)) {
SESSIONS.set(payload.cid!, {
args: this.#config.mochaOpts || {},
Expand Down Expand Up @@ -146,7 +152,7 @@ export default class BrowserRunner extends LocalRunner {
}

if (payload.name === 'workerHookResult') {
this.#server.resolveHook(payload.args)
workerServer.resolveHook(payload.args)
}

if (payload.name === 'coverageMap') {
Expand Down

0 comments on commit 7623741

Please sign in to comment.