fix(infra): retry type generation (#13385)

* fix(infra): retry type generation

* remove link

* remove package linking in pipelines

* fix path in smoke tests

* remove another link call

* better resolve wdio modules in browser-runner

* fixes

* make it work on Windows

* more fixes

* more windows fixes

* unit test fix

* another windows fix

* fix e2e commands

* remove shx dep
This commit is contained in:
Christian Bromann 2024-08-18 19:06:55 -07:00 committed by GitHub
parent 0da85de8c1
commit b84bcf6d76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 177 additions and 157 deletions

View file

@ -24,10 +24,6 @@ jobs:
path: .
filename: webdriverio-build.zip
- name: Link Packages
run: pnpm run link
shell: bash
- name: E2E Connection Test
run: pnpm run test:e2e:cloud
if: github.ref == 'refs/heads/main'

View file

@ -34,10 +34,6 @@ jobs:
path: .
filename: webdriverio-build.zip
- name: Link Packages
run: pnpm run link
shell: bash
- name: Component Tests
run: pnpm run test:component
# component testing on Windows is currently broken

View file

@ -24,9 +24,7 @@ jobs:
filename: webdriverio-build.zip
- name: CJS Interoperability Tests
run: |
pnpm run link
pnpm run test:interop
run: pnpm run test:interop
shell: bash
- name: Check Git Context

View file

@ -27,10 +27,6 @@ jobs:
path: .
filename: webdriverio-build.zip
- name: Link Packages
run: pnpm run link
shell: bash
- name: E2E Launch Tests
run: pnpm run test:e2e:webdriver
shell: bash

View file

@ -27,10 +27,6 @@ jobs:
path: .
filename: webdriverio-build.zip
- name: Link Packages
run: pnpm run link
shell: bash
- name: Testrunner Multiremote Tests
run: pnpm run test:e2e:multiremote
shell: bash

View file

@ -34,10 +34,6 @@ jobs:
path: .
filename: webdriverio-build.zip
- name: Link Packages
run: pnpm run link
shell: bash
- name: Smoke Tests
run: pnpm run test:smoke
shell: bash

View file

@ -27,10 +27,6 @@ jobs:
path: .
filename: webdriverio-build.zip
- name: Link Packages
run: pnpm run link
shell: bash
- name: E2E Standalone Tests
run: pnpm run test:e2e:standalone
shell: bash

View file

@ -27,10 +27,6 @@ jobs:
path: .
filename: webdriverio-build.zip
- name: Link Packages
run: pnpm run link
shell: bash
- name: Testrunner Tests
run: pnpm run test:e2e:testrunner
shell: bash

View file

@ -6,33 +6,33 @@
"scripts": {
"test:browser": "run-s test:browser:*",
"test:browser:react": "run-s test:browser:react:*",
"test:browser:react:wdio": "cross-env WDIO_PRESET=react node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec react.test.tsx",
"test:browser:react:wdio": "cross-env WDIO_PRESET=react wdio ./browser-runner/wdio.conf.js --spec react.test.tsx",
"test:browser:react:verifyCoverage": "run-s verifyCoverage",
"test:browser:preact": "run-s test:browser:preact:*",
"test:browser:preact:wdio": "cross-env WDIO_PRESET=preact node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec pr-eact.test.tsx",
"test:browser:preact:wdio": "cross-env WDIO_PRESET=preact wdio ./browser-runner/wdio.conf.js --spec pr-eact.test.tsx",
"test:browser:preact:verifyCoverage": "run-s verifyCoverage",
"test:browser:vue": "run-s test:browser:vue:*",
"test:browser:vue:copyTW": "cp ./__fixtures__/tailwind.config.js ./tailwind.config.js",
"test:browser:vue:wdio": "cross-env WDIO_PRESET=vue node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec vue.test.js",
"test:browser:vue:wdio": "cross-env WDIO_PRESET=vue wdio ./browser-runner/wdio.conf.js --spec vue.test.js",
"test:browser:vue:deleteTW": "rm ./tailwind.config.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 svelte.test.js",
"test:browser:svelte:wdio": "cross-env WDIO_PRESET=svelte wdio ./browser-runner/wdio.conf.js --spec 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 lit.test.js",
"test:browser:lit:wdio": "cross-env WDIO_PRESET=lit wdio ./browser-runner/wdio.conf.js --spec lit.test.js",
"test:browser:lit:verifyCoverage": "run-s verifyCoverage",
"test:browser:lit:verifyScreenshotFile": "test -f ./screenshot.png && rm ./screenshot.png",
"test:browser:stencil": "run-s test:browser:stencil:*",
"test:browser:stencil:wdio": "cross-env WDIO_PRESET=stencil node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec stencil.test.tsx",
"test:browser:stencil:wdio": "cross-env WDIO_PRESET=stencil wdio ./browser-runner/wdio.conf.js --spec stencil.test.tsx",
"test:browser:stencil:verifyCoverage": "run-s verifyCoverage",
"test:browser:misc": "node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec mock.test.ts",
"test:mocha": "node ../packages/wdio-cli/bin/wdio.js ./mocha/wdio.conf.js",
"test:jasmine": "node ../packages/wdio-cli/bin/wdio.js ./jasmine/wdio.conf.js",
"test:cucumber": "node ../packages/wdio-cli/bin/wdio.js ./cucumber/wdio.conf.js",
"test:multiremote": "node ../packages/wdio-cli/bin/wdio.js ./wdio/wdio-multiremote.conf.ts",
"test:customReporter": "node ../packages/wdio-cli/bin/wdio.js ./custom-reporter/wdio.conf.js",
"test:customService": "node ../packages/wdio-cli/bin/wdio.js ./custom-service/wdio.conf.js",
"test:browser:misc": "wdio ./browser-runner/wdio.conf.js --spec mock.test.ts",
"test:mocha": "wdio ./mocha/wdio.conf.js",
"test:jasmine": "wdio ./jasmine/wdio.conf.js",
"test:cucumber": "wdio ./cucumber/wdio.conf.js",
"test:multiremote": "wdio ./wdio/wdio-multiremote.conf.ts",
"test:customReporter": "wdio ./custom-reporter/wdio.conf.js",
"test:customService": "wdio ./custom-service/wdio.conf.js",
"verifyCoverage": "test -d ./browser-runner/coverage"
},
"devDependencies": {
@ -49,11 +49,15 @@
"@vue/compiler-dom": "^3.4.19",
"@vue/test-utils": "^2.4.3",
"@wdio/browser-runner": "workspace:*",
"@wdio/config": "workspace:*",
"@wdio/cli": "workspace:*",
"@wdio/dot-reporter": "workspace:*",
"@wdio/globals": "workspace:*",
"@wdio/junit-reporter": "workspace:*",
"@wdio/lighthouse-service": "workspace:*",
"@wdio/local-runner": "workspace:*",
"@wdio/mocha-framework": "workspace:*",
"@wdio/repl": "workspace:*",
"@wdio/shared-store-service": "workspace:*",
"@wdio/spec-reporter": "workspace:*",
"@wdio/types": "workspace:*",

View file

@ -38,7 +38,12 @@ const projects = (await fs.readdir(
const packages = (
await Promise.all(
projects.map(async (project) => {
const pkg = await import(path.resolve(rootDir, 'packages', project, 'package.json'), { assert: { type: 'json' } })
const pkg = await import(
url.pathToFileURL(
path.resolve(rootDir, 'packages', project, 'package.json')
).href,
{ assert: { type: 'json' } }
)
return [project, pkg.default]
})
) as [string, PackageJson][]
@ -125,7 +130,7 @@ const configs = packages.map(([packageDir, pkg]) => {
* if types field is a string, generate TypeScript declarations
*/
if (typeof exp.types === 'string' && target === '.') {
esmBuild.plugins?.push(generateDts(absWorkingDir))
esmBuild.plugins?.push(generateDts(absWorkingDir, pkg))
}
if (values.clear) {

View file

@ -1,12 +1,23 @@
import cp from 'node:child_process'
import cp, { type ExecException } from 'node:child_process'
import url from 'node:url'
import path from 'node:path'
import util from 'node:util'
import chalk from 'chalk'
import { rimraf } from 'rimraf'
import { copy } from 'esbuild-plugin-copy'
import type { Plugin, BuildOptions } from 'esbuild'
import type { PackageJson } from 'type-fest'
const MAX_RETRIES = 3
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
const exec = util.promisify(cp.exec)
const tscPath = path.resolve(path.dirname(url.fileURLToPath(import.meta.resolve('typescript'))), '..', 'bin', 'tsc')
const l = {
format: (format: string = 'unknown') => chalk.yellowBright(format),
file: (file: string = 'unknown') => chalk.blueBright(file),
name: (name: string = 'unknown') => chalk.hex('#EA5907')(`[${name}]`)
}
/**
* little logger plugin for Esbuild
@ -21,11 +32,11 @@ export function log(options: BuildOptions, pkg: PackageJson): Plugin {
name: 'LogPlugin',
setup(build) {
build.onStart(() => {
console.log(`🏗️ Building "${pkg.name}" for ${options.format}: ${srcFile} → ${outFile}`)
console.log(`${l.name(pkg.name)} 🏗️ Building ${l.format(options.format)} package: ${l.file(srcFile)} → ${l.file(outFile)}`)
})
build.onEnd((result) => {
if (result.errors.length === 0) {
console.log(`✅ Success building "${pkg.name}" for ${options.format}: ${srcFile} → ${outFile}`)
console.log(`${l.name(pkg.name)} ✅ Success building ${l.format(options.format)} package: ${l.file(srcFile)} → ${l.file(outFile)}`)
}
})
}
@ -54,28 +65,44 @@ export function clear(config: BuildOptions): Plugin {
}
}
/**
* Generates type definition files (d.ts) for a given package.
*
* @param {string} cwd - The current working directory.
* @param {PackageJson} pkg - The package JSON object.
* @param {number} [retry=MAX_RETRIES] - The number of retries.
* @return {Promise<void>} A promise that resolves when the types are generated.
*/
function generateTypes(cwd: string, pkg: PackageJson, retry = MAX_RETRIES): Promise<void> {
const child = exec(`node ${tscPath} --emitDeclarationOnly`, { cwd })
return child.then(() => {}, (err) => {
if (retry > 0) {
console.log(`${l.name(pkg.name)} ↻ Retrying (${MAX_RETRIES - (retry - 1)}/${MAX_RETRIES}) building types for ${pkg.name}`)
return generateTypes(cwd, pkg, retry - 1)
}
const error: ExecException = err instanceof Error ? err : new Error(`unknown error: ${err}`)
throw new Error(`[${pkg.name}] Failed to generate d.ts files: ${error.message}\n${error.stdout}`)
})
}
/**
* generate type definition files (d.ts) for working dir
* @param {string} absWorkingDir absolute path to the working directory
* @returns an Esbuild plugin
*/
export function generateDts(absWorkingDir: string): Plugin {
export function generateDts(absWorkingDir: string, pkg: PackageJson): Plugin {
return {
name: 'TypeScriptDeclarationsPlugin',
setup(build) {
build.onEnd((result) => {
build.onEnd(async (result) => {
/**
* don't build types if we failed already somewhere else
*/
if (result.errors.length > 0) {
return
}
try {
cp.execSync('tsc --emitDeclarationOnly', {
cwd: absWorkingDir,
stdio: 'inherit'
})
} catch {
console.log('Failed to generate TypeScript declarations')
}
await generateTypes(absWorkingDir, pkg)
})
}
}

View file

@ -25,9 +25,8 @@
"compile:all:all": "pnpm -r --filter=@wdio/compiler run build",
"generate": "run-s generate:*",
"generate:bidi": "tsx ./scripts/bidi/index.ts",
"link": "tsx ./scripts/link.ts",
"pushReleaseTag": "tsx ./scripts/pushTags.ts",
"setup": "run-s clean link build",
"setup": "run-s clean build",
"docs": "run-s docs:*",
"docs:setup": "cd ./website && pnpm install && cd ..",
"docs:generate": "run-s clean:website generate:bidi && tsx ./scripts/docs-generation/generateDocs.ts",
@ -37,7 +36,7 @@
"test:depcheck": "tsx ./scripts/depcheck.ts",
"test:eslint": "eslint --cache packages examples scripts tests",
"test:ejslint": "ejslint packages/wdio-cli/src/templates/**/*",
"test:interop": "pnpm install && node tests/interop/webdriverio.e2e.js && node tests/interop/webdriver.e2e.js && node tests/interop/cucumber-framework.e2e.js && node tests/interop/allure-reporter.e2e.js && node tests/interop/shared-store.e2e.js && node tests/interop/wdio-cli.e2e.js && node tests/interop/wdio-reporter.e2e.js",
"test:interop": "pnpm install && cd ./tests && node ./interop/webdriverio.e2e.js && node ./interop/webdriver.e2e.js && node ./interop/cucumber-framework.e2e.js && node ./interop/allure-reporter.e2e.js && node ./interop/shared-store.e2e.js && node ./interop/wdio-cli.e2e.js && node ./interop/wdio-reporter.e2e.js",
"test:typings": "pnpm install && run-p test:typings:*",
"test:typings:webdriver": "cd tests/typings/webdriver && npx tsc --skipLibCheck",
"test:typings:webdriverio": "cd tests/typings/webdriverio && npx tsc --skipLibCheck",
@ -49,12 +48,12 @@
"test:unit:watch": "vitest --config vitest.config.ts --watch",
"test:component": "run-s test:component:*",
"test:component:run": "cd e2e && pnpm test:browser",
"test:smoke": "node ./tests/smoke.runner.js",
"test:e2e:testrunner": "node ./packages/wdio-cli/bin/wdio.js ./e2e/wdio/wdio.conf.ts",
"test:e2e:multiremote": "node ./packages/wdio-cli/bin/wdio.js ./e2e/wdio/wdio-multiremote.conf.ts",
"test:smoke": "cd ./tests && node ./smoke.runner.js",
"test:e2e:testrunner": "cd ./e2e && npx wdio run ./wdio/wdio.conf.ts",
"test:e2e:multiremote": "cd ./e2e && npx wdio run ./wdio/wdio-multiremote.conf.ts",
"test:e2e:standalone": "vitest --config ./e2e/vitest.config.ts --run",
"test:e2e:webdriver": "node ./packages/wdio-cli/bin/wdio.js ./e2e/wdio/wdio.local.conf.ts",
"test:e2e:cloud": "tsx ./packages/wdio-cli/bin/wdio.js ./e2e/wdio/wdio.sauce.conf.ts",
"test:e2e:webdriver": "cd ./e2e && npx wdio run ./wdio/wdio.local.conf.ts",
"test:e2e:cloud": "cd ./e2e && npx wdio run ./wdio/wdio.sauce.conf.ts",
"dev": "pnpm -r --filter=@wdio/compiler run build --watch",
"watch:docs": "pnpm docs:generate && cd website && npm i && npm start",
"version": "pnpm changelog && git add CHANGELOG.md",
@ -89,6 +88,8 @@
"@vitejs/plugin-react": "^4.3.1",
"@vitejs/plugin-vue": "^5.1.2",
"@vitest/coverage-v8": "^2.0.5",
"@wdio/config": "workspace:*",
"@wdio/repl": "workspace:*",
"camelcase": "^8.0.0",
"cddl": "^0.8.5",
"cddl2ts": "^0.2.2",
@ -118,7 +119,6 @@
"recursive-readdir": "^2.2.3",
"rimraf": "^6.0.1",
"shelljs": "^0.8.5",
"shx": "^0.3.4",
"tempy": "^3.1.0",
"tsd": "^0.31.1",
"tsx": "^4.16.5",

View file

@ -88,7 +88,7 @@ export class MochaFramework extends HTMLElement {
const globalTeardownScripts: Function[] = []
const globalSetupScripts: Function[] = []
for (const r of this.#require) {
const { mochaGlobalSetup, mochaGlobalTeardown } = (await import(r)) || {}
const { mochaGlobalSetup, mochaGlobalTeardown } = (await import(/* @vite-ignore */r)) || {}
if (typeof mochaGlobalSetup === 'function') {
globalSetupScripts.push(mochaGlobalSetup)
}
@ -112,7 +112,7 @@ export class MochaFramework extends HTMLElement {
* import test case (order is important here)
*/
const file = this.#spec
await import(file)
await import(/* @vite-ignore */file)
/**
* run setup scripts

View file

@ -1,3 +1,4 @@
import logger from '@wdio/logger'
import topLevelAwait from 'vite-plugin-top-level-await'
import { esbuildCommonjs } from '@originjs/vite-plugin-commonjs'
import type { InlineConfig } from 'vite'
@ -5,6 +6,8 @@ import type { InlineConfig } from 'vite'
import { codeFrameFix } from './plugins/esbuild.js'
import type { FrameworkPreset } from '../types.js'
const log = logger('@wdio/browser-runner:vite')
export const DEFAULT_PROTOCOL = 'http'
export const DEFAULT_HOSTNAME = 'localhost'
export const DEFAULT_HOST = `${DEFAULT_PROTOCOL}://${DEFAULT_HOSTNAME}`
@ -30,7 +33,7 @@ export const PRESET_DEPENDENCIES: Record<FrameworkPreset, [string, string, any]
export const DEFAULT_VITE_CONFIG: Partial<InlineConfig> = {
configFile: false,
server: { host: DEFAULT_HOSTNAME },
logLevel: 'silent',
logLevel: 'info',
plugins: [topLevelAwait()],
build: {
sourcemap: 'inline',
@ -59,5 +62,14 @@ export const DEFAULT_VITE_CONFIG: Partial<InlineConfig> = {
codeFrameFix()
],
},
},
customLogger: {
info: (msg: string) => log.info(msg),
warn: (msg: string) => log.warn(msg),
warnOnce: (msg: string) => log.warn(msg),
error: (msg: string) => log.error(msg),
clearScreen: () => {},
hasErrorLogged: () => false,
hasWarned: false
}
}

View file

@ -92,7 +92,7 @@ export function testrunner(options: WebdriverIO.BrowserRunnerOptions): Plugin[]
}
if (id === '@wdio/logger') {
const newId = url.fileURLToPath(await resolve(id, import.meta.url))
const newId = await resolveWDIOModule(id)
return path.resolve(path.dirname(newId), 'browser.js')
}
@ -100,7 +100,8 @@ export function testrunner(options: WebdriverIO.BrowserRunnerOptions): Plugin[]
* make sure WDIO imports are resolved properly as ESM module
*/
if (id.startsWith('@wdio') || WDIO_PACKAGES.includes(id)) {
return url.fileURLToPath(await resolve(id, import.meta.url))
const resolvedId = await resolveWDIOModule(id)
return resolvedId
}
/**
@ -193,3 +194,19 @@ export function testrunner(options: WebdriverIO.BrowserRunnerOptions): Plugin[]
},
}]
}
/**
* Resolves the path of a WDIO module.
*
* @param {string} pkgName - The name of the WDIO module to resolve.
* @return {string} The resolved path of the WDIO module.
*/
async function resolveWDIOModule (pkgName: string) {
try {
const pkgPath = await resolve(pkgName, import.meta.url)
return url.fileURLToPath(pkgPath)
} catch {
const pkgPath = await resolve(pkgName, url.pathToFileURL(path.resolve(process.cwd())).href)
return url.fileURLToPath(pkgPath)
}
}

View file

@ -1,3 +1,4 @@
import os from 'node:os'
import url from 'node:url'
import path from 'node:path'
import fs from 'node:fs'
@ -341,8 +342,12 @@ class CucumberAdapter {
async loadFilesWithType(fileList: string[]) {
return fileList.reduce(
(files: string[], file: string) =>
files.concat(isGlob(file) ? globSync(file) : [file]),
(files: string[], file: string) => {
const filePath = os.platform() === 'win32'
? url.pathToFileURL(file).href
: file
return files.concat(isGlob(filePath) ? globSync(filePath) : [filePath])
},
[]
)
}
@ -351,11 +356,11 @@ class CucumberAdapter {
const importedModules = []
for (const module of modules) {
const filepath = path.isAbsolute(module)
? module.startsWith(FILE_PROTOCOL)
? module
: url.pathToFileURL(module).href
: url.pathToFileURL(path.join(process.cwd(), module)).href
const filepath = module.startsWith(FILE_PROTOCOL)
? module
: path.isAbsolute(module)
? url.pathToFileURL(module).href
: url.pathToFileURL(path.join(process.cwd(), module)).href
// This allows rerunning a stepDefinitions file
const stepDefPath = url.pathToFileURL(
require.resolve(url.fileURLToPath(filepath))

View file

@ -199,7 +199,7 @@ describe('CucumberAdapter', () => {
it('loadSpecFiles', async () => {
const adapter = await CucumberAdapter.init!('0-0', {}, ['/foo/bar'], {}, {}, {}, false, ['progress'])
adapter.loadFilesWithType = vi.fn().mockReturnValue([process.cwd() + '/__mocks__/moduleC.ts'])
adapter.loadFilesWithType = vi.fn().mockReturnValue([path.resolve(process.cwd(), '__mocks__', 'moduleC.ts')])
expect(global.MODULE_C_WAS_LOADED).toBe(undefined)
await adapter.loadFiles()

View file

@ -145,7 +145,7 @@ export function setupEnv (cid: string, options: MochaOpts, beforeTest: Hook, bef
export async function loadModule (name: string) {
try {
return await import(name)
return await import(/* @vite-ignore */name)
} catch (err: any) {
throw new Error(`Module ${name} can't get loaded. Are you sure you have installed it?\n` +
'Note: if you\'ve installed WebdriverIO globally you need to install ' +

View file

@ -4,7 +4,7 @@ import path from 'node:path'
export default class SmokeServiceLauncher {
logFile: fs.WriteStream
constructor () {
this.logFile = fs.createWriteStream(path.join(process.cwd(), 'tests', 'helpers', 'launcher.log'))
this.logFile = fs.createWriteStream(path.resolve(__dirname, '..', '..', '..', 'tests', 'helpers', 'launcher.log'))
}
onPrepare () { this.logFile.write('onPrepare called\n') } // eslint-disable-line no-console
onWorkerStart () { this.logFile.write('onWorkerStart called\n')} // eslint-disable-line no-console

View file

@ -4,7 +4,7 @@ import path from 'node:path'
export default class SmokeService {
logFile: fs.WriteStream
constructor () {
this.logFile = fs.createWriteStream(path.join(process.cwd(), 'tests', 'helpers', 'service.log'))
this.logFile = fs.createWriteStream(path.resolve(__dirname, '..', '..', '..', 'tests', 'helpers', 'service.log'))
}
beforeSession () { this.logFile.write('beforeSession called\n') } // eslint-disable-line no-console
before () { this.logFile.write('before called\n') } // eslint-disable-line no-console

View file

@ -1,10 +1,13 @@
import fs from 'node:fs'
import url from 'node:url'
import path from 'node:path'
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
export default class SmokeService {
logFile: fs.WriteStream
constructor () {
this.logFile = fs.createWriteStream(path.join(process.cwd(), 'tests', 'helpers', 'service.log'))
this.logFile = fs.createWriteStream(path.resolve(__dirname, '..', '..', '..', 'tests', 'helpers', 'service.log'))
}
beforeSession () { this.logFile.write('beforeSession called\n') } // eslint-disable-line no-console
before () { this.logFile.write('before called\n') } // eslint-disable-line no-console
@ -25,7 +28,7 @@ export default class SmokeService {
class SmokeServiceLauncher {
logFile: fs.WriteStream
constructor () {
this.logFile = fs.createWriteStream(path.join(process.cwd(), 'tests', 'helpers', 'launcher.log'))
this.logFile = fs.createWriteStream(path.resolve(__dirname, '..', '..', '..', 'tests', 'helpers', 'launcher.log'))
}
onPrepare () { this.logFile.write('onPrepare called\n') } // eslint-disable-line no-console
onWorkerStart () { this.logFile.write('onWorkerStart called\n')} // eslint-disable-line no-console

View file

@ -1,4 +1,3 @@
/// <reference types="@wdio/globals/types" />
import logger from '@wdio/logger'
import type { Frameworks } from '@wdio/types'

View file

@ -1,5 +1,7 @@
import fs from 'node:fs/promises'
import url from 'node:url'
import path from 'node:path'
import type { Options, Services } from '@wdio/types'
import { SUPPORTED_BROWSERNAMES, DEFAULT_PROTOCOL, DEFAULT_HOSTNAME, DEFAULT_PATH } from './constants.js'
@ -177,7 +179,7 @@ export function getArgumentType (arg: any) {
*/
export async function userImport<T> (moduleName: string, namedImport = 'default'): Promise<T> {
try {
const mod = await import(moduleName)
const mod = await import(/* @vite-ignore */moduleName)
if (namedImport in mod) {
return mod[namedImport]
}
@ -219,11 +221,9 @@ export async function safeImport (name: string): Promise<Services.ServicePlugin
try {
importPath = await resolve(name, import.meta.url)
} catch (err: any) {
const { join } = await import('node:path')
const { pathToFileURL } = await import('node:url')
const localNodeModules = join(process.cwd(), 'node_modules')
const localNodeModules = path.join(process.cwd(), 'node_modules')
try {
importPath = await resolve(name, pathToFileURL(localNodeModules).toString())
importPath = await resolve(name, url.pathToFileURL(localNodeModules).toString())
} catch (err: any) {
return null
}
@ -234,7 +234,7 @@ export async function safeImport (name: string): Promise<Services.ServicePlugin
}
try {
const pkg = await import(importPath)
const pkg = await import(/* @vite-ignore */importPath)
/**
* CJS packages build with TS imported through an ESM context can end up being this:

View file

@ -80,7 +80,7 @@ export async function reloadSession (this: WebdriverIO.Browser, newCapabilities?
log.debug('Disconnected puppeteer session')
}
const ProtocolDriver = (await import(this.options.automationProtocol!)).default
const ProtocolDriver = (await import(/* @vite-ignore */this.options.automationProtocol!)).default
await ProtocolDriver.reloadSession(this, newCapabilities)
const options = this.options as Options.Testrunner

View file

@ -168,7 +168,7 @@ export const multiremote = async function (
}
const ProtocolDriver = automationProtocol && isStub(automationProtocol)
? (await import(automationProtocol)).default
? (await import(/* @vite-ignore */automationProtocol)).default
: WebDriver
const driver = ProtocolDriver.attachToSession(
sessionParams,

View file

@ -36,6 +36,6 @@ export async function getProtocolDriver (options: Capabilities.WebdriverIOConfig
Object.assign(options, detectBackend(options))
}
const Driver = webdriverImport || (await import(options.automationProtocol || 'webdriver')).default
const Driver = webdriverImport || (await import(/* @vite-ignore */options.automationProtocol || 'webdriver')).default
return { Driver, options }
}

View file

@ -89,6 +89,12 @@ importers:
'@vitest/coverage-v8':
specifier: ^2.0.5
version: 2.0.5(vitest@2.0.5(@types/node@20.14.15)(jsdom@24.1.1)(terser@5.31.6))
'@wdio/config':
specifier: workspace:*
version: link:packages/wdio-config
'@wdio/repl':
specifier: workspace:*
version: link:packages/wdio-repl
camelcase:
specifier: ^8.0.0
version: 8.0.0
@ -176,9 +182,6 @@ importers:
shelljs:
specifier: ^0.8.5
version: 0.8.5
shx:
specifier: ^0.3.4
version: 0.3.4
tempy:
specifier: ^3.1.0
version: 3.1.0
@ -261,9 +264,18 @@ importers:
'@wdio/cli':
specifier: workspace:*
version: link:../packages/wdio-cli
'@wdio/config':
specifier: workspace:*
version: link:../packages/wdio-config
'@wdio/dot-reporter':
specifier: workspace:*
version: link:../packages/wdio-dot-reporter
'@wdio/globals':
specifier: workspace:*
version: link:../packages/wdio-globals
'@wdio/junit-reporter':
specifier: workspace:*
version: link:../packages/wdio-junit-reporter
'@wdio/lighthouse-service':
specifier: workspace:*
version: link:../packages/wdio-lighthouse-service
@ -273,6 +285,9 @@ importers:
'@wdio/mocha-framework':
specifier: workspace:*
version: link:../packages/wdio-mocha-framework
'@wdio/repl':
specifier: workspace:*
version: link:../packages/wdio-repl
'@wdio/shared-store-service':
specifier: workspace:*
version: link:../packages/wdio-shared-store-service
@ -11647,11 +11662,6 @@ packages:
engines: {node: '>=4'}
hasBin: true
shx@0.3.4:
resolution: {integrity: sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==}
engines: {node: '>=6'}
hasBin: true
side-channel@1.0.6:
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
engines: {node: '>= 0.4'}
@ -26073,11 +26083,6 @@ snapshots:
interpret: 1.4.0
rechoir: 0.6.2
shx@0.3.4:
dependencies:
minimist: 1.2.8
shelljs: 0.8.5
side-channel@1.0.6:
dependencies:
call-bind: 1.0.7

View file

@ -1,27 +0,0 @@
#!/usr/bin/env node
/**
* This script initializes the playground by linking all package into the /test directory
*/
import url from 'node:url'
import path from 'node:path'
import shell from 'shelljs'
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
const packagesDir = path.join(__dirname, '..', 'packages')
const nodeModulesDir = path.join(__dirname, '..', 'packages', 'node_modules')
const nodeModulesWDIODir = path.join(__dirname, '..', 'packages', 'node_modules', '@wdio')
const packages = shell.ls(packagesDir)
shell.mkdir(nodeModulesDir)
shell.mkdir(nodeModulesWDIODir)
packages.forEach(
(pkg) => shell.ln(
'-s',
path.join(packagesDir, pkg),
pkg.startsWith('wdio-')
? path.join(nodeModulesWDIODir, pkg.replace('wdio-', ''))
: path.join(nodeModulesDir, pkg)
)
)

View file

@ -39,6 +39,6 @@ export const config = {
cucumberOpts: {
timeout: 5000,
requireModule: ['tsx'],
require: ['./tests/cucumber/step-definitions/*.js']
require: [path.resolve(__dirname, '..', 'cucumber', 'step-definitions', '*.js')]
}
}

View file

@ -68,7 +68,7 @@ async function runTests (tests) {
const mochaTestrunner = async () => {
const { skippedSpecs } = await launch('mochaTestrunner', baseConfig, {
specs: [
'../mocha/test.ts',
'./mocha/test.ts',
path.resolve(__dirname, 'mocha', 'test-middleware.ts'),
path.resolve(__dirname, 'mocha', 'test-waitForElement.ts'),
path.resolve(__dirname, 'mocha', 'test-skipped.ts'),
@ -95,7 +95,7 @@ const mochaAsyncTestrunner = async () => {
'mochaAsyncTestrunner',
path.resolve(__dirname, 'helpers', 'command.hook.config.js'),
{
spec: ['./tests/mocha/test-async.ts']
spec: ['./mocha/test-async.ts']
}
)
assert.strictEqual(skippedSpecs, 0)
@ -169,7 +169,7 @@ const jasmineReporter = async () => {
outputDir: __dirname + '/jasmine'
}).catch((err) => err) // error expected
await sleep(100)
const reporterLogsPath = path.join(__dirname, 'jasmine', 'wdio-0-0-smoke-test-reporter.log')
const reporterLogsPath = path.resolve(__dirname, 'jasmine', 'wdio-0-0-smoke-test-reporter.log')
const reporterLogs = await fs.readFile(reporterLogsPath)
expect(reporterLogs.toString()).toEqual(JASMINE_REPORTER_LOGS)
await fs.unlink(reporterLogsPath)
@ -179,7 +179,7 @@ const jasmineReporter = async () => {
* Jasmine timeout test
*/
const jasmineTimeout = async () => {
const logFile = path.join(__dirname, 'jasmineTimeout.spec.log')
const logFile = path.resolve(__dirname, 'jasmineTimeout.spec.log')
await launch('jasmineTimeout', baseConfig, {
specs: [path.resolve(__dirname, 'jasmine', 'test-timeout.js')],
reporters: [
@ -217,7 +217,7 @@ const jasmineTimeout = async () => {
* https://github.com/webdriverio/webdriverio/issues/8979
*/
const jasmineAfterAll = async () => {
const logFile = path.join(__dirname, 'jasmineAfterAll.spec.log')
const logFile = path.resolve(__dirname, 'jasmineAfterAll.spec.log')
await launch('jasmineAfterAll', baseConfig, {
specs: [path.resolve(__dirname, 'jasmine', 'afterAll-report.js')],
reporters: [
@ -255,7 +255,7 @@ const jasmineAfterAll = async () => {
* Jasmine verify failSpecWithNoExpectations support
*/
const jasmineFailSpecWithNoExpectations = async () => {
const logFile = path.join(__dirname, 'jasmineWithNoExpectations.spec.log')
const logFile = path.resolve(__dirname, 'jasmineWithNoExpectations.spec.log')
await launch('jasmineAfterAll', baseConfig, {
specs: [path.resolve(__dirname, 'jasmine', 'jasmineWithNoExpectations.js')],
reporters: [
@ -307,7 +307,7 @@ const cucumberTestrunner = async () => {
* Cucumber wdio testrunner -- run single scenario by line number
*/
const cucumberTestrunnerByLineNumber = async () => {
const logFile = path.join(__dirname, 'cucumber', 'cucumberTestrunnerByLineNumber.log')
const logFile = path.resolve(__dirname, 'cucumber', 'cucumberTestrunnerByLineNumber.log')
await fs.rm(logFile, { force: true })
await launch(
'cucumberTestrunnerByLineNumber',
@ -389,9 +389,9 @@ const customService = async () => {
services: [['smoke-test', { foo: 'bar' }]]
})
await sleep(100)
const serviceLogs = await fs.readFile(path.join(__dirname, 'helpers', 'service.log'))
const serviceLogs = await fs.readFile(path.resolve(__dirname, 'helpers', 'service.log'))
assert.equal(serviceLogs.toString(), SERVICE_LOGS)
const launcherLogs = await fs.readFile(path.join(__dirname, 'helpers', 'launcher.log'))
const launcherLogs = await fs.readFile(path.resolve(__dirname, 'helpers', 'launcher.log'))
assert.equal(launcherLogs.toString(), LAUNCHER_LOGS)
}
@ -404,9 +404,9 @@ const customCJSService = async () => {
services: [['smoke-test-cjs', { foo: 'bar' }]]
})
await sleep(100)
const serviceLogs = await fs.readFile(path.join(__dirname, 'helpers', 'service.log'))
const serviceLogs = await fs.readFile(path.resolve(__dirname, 'helpers', 'service.log'))
assert.equal(serviceLogs.toString(), SERVICE_LOGS)
const launcherLogs = await fs.readFile(path.join(__dirname, 'helpers', 'launcher.log'))
const launcherLogs = await fs.readFile(path.resolve(__dirname, 'helpers', 'launcher.log'))
assert.equal(launcherLogs.toString(), LAUNCHER_LOGS)
}
@ -419,7 +419,7 @@ const customReporterString = async () => {
reporters: [['smoke-test', { foo: 'bar' }]]
})
await sleep(100)
const reporterLogsPath = path.join(__dirname, 'helpers', 'wdio-0-0-smoke-test-reporter.log')
const reporterLogsPath = path.resolve(__dirname, 'helpers', 'wdio-0-0-smoke-test-reporter.log')
const reporterLogs = await fs.readFile(reporterLogsPath)
assert.equal(reporterLogs.toString(), REPORTER_LOGS)
await fs.unlink(reporterLogsPath)
@ -434,7 +434,7 @@ const customReporterObject = async () => {
path.resolve(__dirname, 'helpers', 'reporter.conf.js'),
)
await sleep(100)
const reporterLogsWithReporterAsObjectPath = path.join(__dirname, 'helpers', 'wdio-0-0-CustomSmokeTestReporter-reporter.log')
const reporterLogsWithReporterAsObjectPath = path.resolve(__dirname, 'helpers', 'wdio-0-0-CustomSmokeTestReporter-reporter.log')
const reporterLogsWithReporterAsObject = await fs.readFile(reporterLogsWithReporterAsObjectPath)
assert.equal(reporterLogsWithReporterAsObject.toString(), REPORTER_LOGS)
await fs.unlink(reporterLogsWithReporterAsObjectPath)
@ -512,7 +512,7 @@ const retryFail = async () => {
* specfile-level retries (pass)
*/
const retryPass = async () => {
const retryFilename = path.join(__dirname, '.retry_succeeded')
const retryFilename = path.resolve(__dirname, '.retry_succeeded')
const logfiles = ['wdio-0-0.log', 'wdio-0-1.log'].map(f => path.join(__dirname, f))
const rmfiles = [retryFilename, ...logfiles]
for (const filename of rmfiles) {
@ -707,7 +707,7 @@ const runSpecsWithFlagDirectPath = async () => {
'runSpecsWithFlagDirectPath',
path.resolve(severalPassedConfig),
{
spec: ['./tests/tests-cli-spec-arg/mocha.test03.js']
spec: ['./tests-cli-spec-arg/mocha.test03.js']
}
)
assert.strictEqual(passed, 1)
@ -815,7 +815,7 @@ const cliExcludeParamValidationExcludeMultipleSpecsByPath = async () => {
// *** Tests for Jasmine ***
// *************************
const jasmineHooksTestrunner = async () => {
const logFile = path.join(__dirname, 'jasmineHooksTestrunner.spec.log')
const logFile = path.resolve(__dirname, 'jasmineHooksTestrunner.spec.log')
await launch('jasmineHooksTestrunner',
path.resolve(__dirname, 'helpers', 'jasmine-hooks.conf.js'),
{
@ -838,12 +838,12 @@ const jasmineHooksTestrunner = async () => {
}
const jasmineAfterHookArgsValidation = async () => {
const expectedPassedTestResultPath = path.join(__dirname, 'helpers', 'jasmine-after-hook-validation', 'expected-results', 'expectedTestPassed.json')
const expectedFailedTestResultPath = path.join(__dirname, 'helpers', 'jasmine-after-hook-validation', 'expected-results', 'expectedTestFailed.json')
const expectedPassedTestResultPath = path.resolve(__dirname, 'helpers', 'jasmine-after-hook-validation', 'expected-results', 'expectedTestPassed.json')
const expectedFailedTestResultPath = path.resolve(__dirname, 'helpers', 'jasmine-after-hook-validation', 'expected-results', 'expectedTestFailed.json')
// Actual test results are written to files in tests\helpers\jasmine.after-hook-validation.conf.js - afterTest()
const actualPassedTestResultPath = path.join(__dirname, 'helpers', 'actualResultsPassed.log')
const actualFailedTestResultPath = path.join(__dirname, 'helpers', 'actualResultsFailed.log')
const actualPassedTestResultPath = path.resolve(__dirname, 'helpers', 'actualResultsPassed.log')
const actualFailedTestResultPath = path.resolve(__dirname, 'helpers', 'actualResultsFailed.log')
await launch('jasmineAfterHookArgsValidation',
path.resolve(__dirname, 'helpers', 'jasmine.after-hook-validation.conf.js'),