breaking(build): migrate to Esbuild for bundling (#13338)
* breaking(build): migrate to Rollup for bundling * migrate more packages * progress * delete unnecessary tsconfigs * migrate to esbuild * revert npmignore changes * more tweaks * update pnpm-lock * more tweaks * compile scripts within browser environment * fix ts issue in webdriverio * add infra/compiler to readme * fix lock file * remove virtual:wdio from lock file * update docs * fix tests * fix component tests * fix unit tests * clean up * remove original build script * more cleanups * more cleanups * last cleanup
This commit is contained in:
parent
4e349a2d2c
commit
80779bb429
164 changed files with 2221 additions and 1792 deletions
|
|
@ -5,6 +5,5 @@
|
|||
/packages/**/coverage
|
||||
/tests/typings
|
||||
*.d.ts
|
||||
!packages/**/src/cjs
|
||||
packages/wdio-protocols/src/protocols/webdriverBidi.ts
|
||||
packages/webdriverio/third_party/fake-timers.js
|
||||
|
|
|
|||
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
|
|
@ -21,10 +21,6 @@ jobs:
|
|||
env:
|
||||
GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: 🏗️ Generate Typings
|
||||
run: pnpm run generate:typings
|
||||
shell: bash
|
||||
|
||||
- name: ⬆️ Upload Build Artifacts
|
||||
uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
|
|
|
|||
1
.github/workflows/publish.yml
vendored
1
.github/workflows/publish.yml
vendored
|
|
@ -62,7 +62,6 @@ jobs:
|
|||
- name: Release
|
||||
run: |
|
||||
pnpm run setup
|
||||
pnpm run generate:typings
|
||||
pnpm lerna publish ${{github.event.inputs.releaseType}} --exact --yes --dist-tag ${{github.event.inputs.distTag}}
|
||||
pnpm run pushReleaseTag
|
||||
env:
|
||||
|
|
|
|||
|
|
@ -142,13 +142,9 @@ You can immediately start working on the code using [a pre-setup Gitpod environm
|
|||
|
||||
If you have compiled the code this command will remove them as well as all dependencies of the subpackages.
|
||||
|
||||
* Bootstraps sub-projects via ```pnpm run bootstrap```
|
||||
* Compiles the project ```pnpm run compile:all```
|
||||
|
||||
Many packages depend on each other, in order to properly set up the dependency tree you need to run the [Lerna Bootstrap](https://github.com/lerna/lerna#bootstrap) command to create all necessary links. As this project also does some other house keeping tasks, it is recommended to use the package bootstrap command.
|
||||
|
||||
* Builds all subpackages via ```pnpm run build```
|
||||
|
||||
As the last step you need to build all sub-packages in order to resolve the internal dependencies. WebdriverIO uses [TypeScript](https://www.typescriptlang.org/) as a compiler.
|
||||
As the last step you need to build all sub-packages in order to resolve the internal dependencies. WebdriverIO uses [`@wdio/compiler`](https://github.com/webdriverio/webdriverio/tree/main/infa/compiler) which is an internal package that uses Esbuild to compile the project.
|
||||
|
||||
* Run Tests to ensure that everything is set up correctly
|
||||
|
||||
|
|
@ -195,13 +191,7 @@ All type definitions are generated by the TypeScript compiler. There are some es
|
|||
- the `@wdio/protocol` package defines all protocol commands, their function parameters and return types
|
||||
- all other types should be defined in the package where they are used, here we tend to have general types defined in a `types.ts` file
|
||||
|
||||
You can find all files responsible for the generating the typings [here](https://github.com/webdriverio/webdriverio/tree/main/scripts/type-generation). You can trigger the process by calling:
|
||||
|
||||
```sh
|
||||
npm run generate:typings
|
||||
```
|
||||
|
||||
This will run the scripts in the directory shown above and generate the typings for all protocol commands. Whenever you change those [protocol commands](https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-protocols/src/protocols), make sure you re-generate the types with the command shown above.
|
||||
The protocol types are generated as part of the `@wdio/compiler` build command and is part of the [`generate-types`](https://github.com/webdriverio/webdriverio/blob/main/infra/compiler/src/type-generation/index.ts#L27-L35) plugin.
|
||||
|
||||
### Test Changes
|
||||
|
||||
|
|
|
|||
|
|
@ -139,6 +139,12 @@ __Did you build a WebdriverIO service or reporter?__ That's awesome! Please add
|
|||
- [@wdio/smoke-test-service](https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-smoke-test-service) - A WebdriverIO utility to smoke test services for internal testing purposes
|
||||
- [@wdio/webdriver-mock-service](https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-webdriver-mock-service) - A WebdriverIO service to stub all endpoints for internal testing purposes
|
||||
|
||||
### Infrastructure Packages
|
||||
|
||||
These packages are not released to NPM and used to work on this codebase.
|
||||
|
||||
- [@wdio/compiler](https://github.com/webdriverio/webdriverio/tree/main/infa/compiler) - Esbuild script to compile the source code all of all packages
|
||||
|
||||
## :handshake: Project Governance
|
||||
|
||||
This project is maintained by [awesome people](/AUTHORS.md) following a common [set of rules](/GOVERNANCE.md) and treating each other with [respect and appreciation](/CODE_OF_CONDUCT.md).
|
||||
|
|
|
|||
|
|
@ -41,3 +41,22 @@ exports[`snapshot testing > of objects 3`] = `
|
|||
"foo": "bar",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`snapshot testing > of objects 5`] = `
|
||||
{
|
||||
"parsed": {
|
||||
"alpha": 0,
|
||||
"hex": "#000000",
|
||||
"rgba": "rgba(0,0,0,0)",
|
||||
"type": "color",
|
||||
},
|
||||
"property": "background-color",
|
||||
"value": "rgba(0,0,0,0)",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`snapshot testing > of objects 7`] = `
|
||||
{
|
||||
"foo": "bar",
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,6 @@
|
|||
"preact": "^10.19.3",
|
||||
"react": "^18.2.0",
|
||||
"svelte": "^4.2.9",
|
||||
"vue": "^3.4.15"
|
||||
"vue": "^3.4.37"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
32
infra/compiler/README.md
Normal file
32
infra/compiler/README.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# WebdriverIO Build Tool
|
||||
|
||||
This sub-package is being used to build WebdriverIO. It uses [Esbuild](https://esbuild.github.io) to bundle the packages.
|
||||
|
||||
## Usage
|
||||
|
||||
In order to use this package run:
|
||||
|
||||
```sh
|
||||
pnpm -r --filter=@wdio/build run build
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
You can pass in the following options to customize the build command.
|
||||
|
||||
### `-p` / `--project`
|
||||
|
||||
With this argument you can specify which sub package in `<root>/packages` will be build. It accepts either the NPM package name or the directory name. If you omit this parameter the tool will try to build all packages. You can pass in one or multiple packages, e.g.
|
||||
|
||||
```sh
|
||||
$ pnpm -r --filter=@wdio/build run build -p webdriverio -p @wdio/logger -p wdio-globals
|
||||
```
|
||||
|
||||
### `--watch`
|
||||
|
||||
If you pass in this flag, the build task will run within a "watch" context and will continue to run and rebuild individual changes when changes are being made, e.g.
|
||||
|
||||
```sh
|
||||
# watch changes in logger package
|
||||
$ pnpm -r --filter=@wdio/build run build -p @wdio/logger --watch
|
||||
```
|
||||
16
infra/compiler/package.json
Normal file
16
infra/compiler/package.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "@wdio/compiler",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsx ./src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"esbuild": "^0.23.0",
|
||||
"esbuild-plugin-copy": "^2.1.1",
|
||||
"esbuild-plugin-d.ts": "^1.3.0",
|
||||
"camelcase": "^8.0.0",
|
||||
"tsx": "^4.17.0",
|
||||
"type-fest": "^4.24.0"
|
||||
}
|
||||
}
|
||||
227
infra/compiler/src/index.ts
Normal file
227
infra/compiler/src/index.ts
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import url from 'node:url'
|
||||
import { parseArgs } from 'node:util'
|
||||
import { build, context, type BuildOptions, type Plugin } from 'esbuild'
|
||||
import type { PackageJson } from 'type-fest'
|
||||
|
||||
import { getExternal } from './utils.js'
|
||||
import { log, clear, generateDts, copyEJSTemplates, externalScripts } from './plugins.js'
|
||||
import { generateTypes } from './type-generation/index.js'
|
||||
|
||||
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
|
||||
const rootDir = path.resolve(__dirname, '..', '..', '..')
|
||||
const args = process.argv.slice(2)
|
||||
const options = {
|
||||
project: {
|
||||
type: 'string',
|
||||
short: 'p',
|
||||
multiple: true,
|
||||
},
|
||||
watch: {
|
||||
type: 'boolean',
|
||||
},
|
||||
clear: {
|
||||
type: 'boolean'
|
||||
}
|
||||
} as const
|
||||
|
||||
const { values } = parseArgs({ args, options })
|
||||
|
||||
/**
|
||||
* parse through all packages and filter based on command parameters
|
||||
*/
|
||||
const projects = (await fs.readdir(
|
||||
path.resolve(rootDir, 'packages')
|
||||
)).filter((dir) => dir !== 'node_modules')
|
||||
|
||||
const packages = (
|
||||
await Promise.all(
|
||||
projects.map(async (project) => {
|
||||
const pkg = await import(path.resolve(rootDir, 'packages', project, 'package.json'), { assert: { type: 'json' } })
|
||||
return [project, pkg.default]
|
||||
})
|
||||
) as [string, PackageJson][]
|
||||
).filter(([packageDir, pkg]) => (
|
||||
!values.project ||
|
||||
(pkg.name && values.project.includes(pkg.name)) ||
|
||||
values.project.includes(packageDir)
|
||||
))
|
||||
|
||||
/**
|
||||
* plugins for the ESM build
|
||||
*/
|
||||
const esmPlugins: Record<string, Plugin[]> = {
|
||||
'@wdio/protocols': [generateTypes()],
|
||||
'@wdio/cli': [copyEJSTemplates()],
|
||||
'webdriverio': [externalScripts()]
|
||||
}
|
||||
/**
|
||||
* plugins for the cjs build
|
||||
*/
|
||||
const cjsPlugins: Record<string, Plugin[]> = {}
|
||||
/**
|
||||
* plugins for the browser build
|
||||
*/
|
||||
const browserPlugins: Record<string, Plugin[]> = {}
|
||||
|
||||
/**
|
||||
* compose Esbuild configs
|
||||
*/
|
||||
const configs = packages.map(([packageDir, pkg]) => {
|
||||
const packageBuilds: BuildOptions[] = []
|
||||
const exports = (pkg.exports || {}) as PackageJson.ExportConditions
|
||||
|
||||
if (!pkg.name) {
|
||||
throw new Error(`Package in ${packageDir} does not have a "name" field, which is required to build the package`)
|
||||
}
|
||||
|
||||
/**
|
||||
* in cases where we don't have an exports field but a main field
|
||||
* we assume that the main field is the main entry point of the package
|
||||
*/
|
||||
if (!pkg.exports && pkg.main) {
|
||||
exports['.'] = {
|
||||
require: pkg.main
|
||||
}
|
||||
}
|
||||
|
||||
const exportedModules = Object.entries(exports).filter?.(([, exp]) => typeof exp === 'object' && !Array.isArray(exp)) as [string, PackageJson.ExportConditions][]
|
||||
for (const [target, exp] of exportedModules) {
|
||||
const absWorkingDir = path.resolve(rootDir, 'packages', packageDir)
|
||||
const source = (exp.source as string | undefined) || './src/index.ts'
|
||||
const baseConfig: BuildOptions = {
|
||||
sourceRoot: absWorkingDir,
|
||||
tsconfig: path.resolve(absWorkingDir, 'tsconfig.json'),
|
||||
sourcemap: process.env.NODE_ENV !== 'production',
|
||||
external: getExternal(pkg),
|
||||
target: 'node18',
|
||||
bundle: true,
|
||||
absWorkingDir
|
||||
}
|
||||
|
||||
if (typeof exp.import === 'string') {
|
||||
const esmSource = (exp.importSource as string | undefined) || source
|
||||
const esmBuild: BuildOptions = {
|
||||
...baseConfig,
|
||||
entryPoints: [path.resolve(absWorkingDir, esmSource)],
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
plugins: []
|
||||
}
|
||||
|
||||
if (exp.import.endsWith('*')) {
|
||||
esmBuild.outdir = path.resolve(absWorkingDir, path.dirname(exp.import))
|
||||
} else {
|
||||
esmBuild.outfile = path.resolve(absWorkingDir, exp.import)
|
||||
}
|
||||
|
||||
esmBuild.plugins?.push(
|
||||
log(esmBuild, pkg),
|
||||
...(esmPlugins[pkg.name] || [])
|
||||
)
|
||||
|
||||
/**
|
||||
* if types field is a string, generate TypeScript declarations
|
||||
*/
|
||||
if (typeof exp.types === 'string' && target === '.') {
|
||||
esmBuild.plugins?.push(generateDts(absWorkingDir))
|
||||
}
|
||||
|
||||
if (values.clear) {
|
||||
esmBuild.plugins?.push(clear(esmBuild))
|
||||
}
|
||||
|
||||
packageBuilds.push(esmBuild)
|
||||
}
|
||||
|
||||
if (typeof exp.require === 'string') {
|
||||
const requireSource = (exp.requireSource as string | undefined) || source
|
||||
const cjsBuild: BuildOptions = {
|
||||
...baseConfig,
|
||||
external: getExternal(pkg),
|
||||
entryPoints: [path.resolve(absWorkingDir, requireSource)],
|
||||
platform: 'node',
|
||||
format: 'cjs',
|
||||
plugins: [],
|
||||
banner: {
|
||||
'js': 'const __importMetaUrl = require(\'url\').pathToFileURL(__filename).href;'
|
||||
},
|
||||
define: {
|
||||
'import.meta.url': '__importMetaUrl',
|
||||
'import.meta.resolve': 'require.resolve'
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.require.endsWith('*')) {
|
||||
cjsBuild.outdir = path.resolve(absWorkingDir, path.dirname(exp.require))
|
||||
} else {
|
||||
cjsBuild.outfile = path.resolve(absWorkingDir, exp.require)
|
||||
}
|
||||
|
||||
/**
|
||||
* if we define an `index.cts` as require source it is suppose to be a small wrapper
|
||||
* around the main source file that exports the main source file within the CJS context,
|
||||
* hence we need to mark this export as external
|
||||
*/
|
||||
if (requireSource.endsWith('.cts')) {
|
||||
cjsBuild.external?.push('./index.js')
|
||||
}
|
||||
|
||||
cjsBuild.plugins?.push(
|
||||
log(cjsBuild, pkg),
|
||||
...(cjsPlugins[pkg.name] || [])
|
||||
)
|
||||
packageBuilds.push(cjsBuild)
|
||||
}
|
||||
|
||||
if (typeof exp.browser === 'string') {
|
||||
const browserSource = (exp.browserSource as string | undefined) || source
|
||||
const browserBuild: BuildOptions = {
|
||||
...baseConfig,
|
||||
entryPoints: [path.resolve(absWorkingDir, browserSource)],
|
||||
platform: 'browser',
|
||||
format: 'esm',
|
||||
target: ['es2021', 'chrome90', 'edge90', 'firefox90', 'safari12'],
|
||||
plugins: [],
|
||||
supported: {
|
||||
'top-level-await': true //browsers can handle top-level-await features
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.browser.endsWith('*')) {
|
||||
browserBuild.outdir = path.resolve(absWorkingDir, path.dirname(exp.browser))
|
||||
} else {
|
||||
browserBuild.outfile = path.resolve(absWorkingDir, exp.browser)
|
||||
}
|
||||
|
||||
browserBuild.plugins?.push(
|
||||
log(browserBuild, pkg),
|
||||
...(browserPlugins[pkg.name] || [])
|
||||
)
|
||||
|
||||
packageBuilds.push(browserBuild)
|
||||
}
|
||||
}
|
||||
return packageBuilds
|
||||
}).flat()
|
||||
|
||||
if (configs.length === 0) {
|
||||
throw new Error(`No packages found to build using params: ${JSON.stringify(values)}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* build packages
|
||||
*/
|
||||
await Promise.all(configs.map(async (config) => {
|
||||
if (values.watch) {
|
||||
const ctx = await context(config)
|
||||
return ctx.watch()
|
||||
}
|
||||
|
||||
const result = await build(config)
|
||||
if (result.errors.length > 0) {
|
||||
console.error(result.errors)
|
||||
throw new Error('Failed to build packages')
|
||||
}
|
||||
}))
|
||||
116
infra/compiler/src/plugins.ts
Normal file
116
infra/compiler/src/plugins.ts
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
import cp from 'node:child_process'
|
||||
import url from 'node:url'
|
||||
import path from 'node:path'
|
||||
import { rimraf } from 'rimraf'
|
||||
import { copy } from 'esbuild-plugin-copy'
|
||||
import type { Plugin, BuildOptions } from 'esbuild'
|
||||
import type { PackageJson } from 'type-fest'
|
||||
|
||||
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
|
||||
|
||||
/**
|
||||
* little logger plugin for Esbuild
|
||||
* @param {BuildOptions} options Esbuild options
|
||||
* @param {PackageJson} pkg package.json of given project as object
|
||||
* @returns
|
||||
*/
|
||||
export function log(options: BuildOptions, pkg: PackageJson): Plugin {
|
||||
const srcFile = path.relative(options.absWorkingDir || process.cwd(), (options.entryPoints as string[])[0])
|
||||
const outFile = path.relative(options.absWorkingDir || process.cwd(), options.outfile || options.outdir as string)
|
||||
return {
|
||||
name: 'LogPlugin',
|
||||
setup(build) {
|
||||
build.onStart(() => {
|
||||
console.log(`🏗️ Building "${pkg.name}" for ${options.format}: ${srcFile} → ${outFile}`)
|
||||
})
|
||||
build.onEnd((result) => {
|
||||
if (result.errors.length === 0) {
|
||||
console.log(`✅ Success building "${pkg.name}" for ${options.format}: ${srcFile} → ${outFile}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clear previously generated build files
|
||||
* @param {string} outfile directory that Esbuild usually compiles to
|
||||
* @returns an Esbuild plugin
|
||||
*/
|
||||
export function clear(config: BuildOptions): Plugin {
|
||||
const rimrafOptions = { maxRetries: 1 }
|
||||
const outfile = config.outfile || config.outdir
|
||||
if (!outfile) {
|
||||
throw new Error('No outfile defined')
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'ClearPlugin',
|
||||
async setup() {
|
||||
await Promise.all([
|
||||
rimraf(path.dirname(outfile), rimrafOptions),
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
return {
|
||||
name: 'TypeScriptDeclarationsPlugin',
|
||||
setup(build) {
|
||||
build.onEnd((result) => {
|
||||
if (result.errors.length > 0) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
cp.execSync('tsc --emitDeclarationOnly', {
|
||||
cwd: absWorkingDir,
|
||||
stdio: 'inherit'
|
||||
})
|
||||
} catch {
|
||||
console.log('Failed to generate TypeScript declarations')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin to copy EJS templates from the `@wdio/cli` package to build directory
|
||||
* @returns {Plugin} an Esbuild plugin
|
||||
*/
|
||||
export function copyEJSTemplates () {
|
||||
const cliPackage = path.resolve(__dirname, '..', '..', 'packages', 'wdio-cli')
|
||||
return copy({
|
||||
resolveFrom: cliPackage,
|
||||
assets: [{
|
||||
from: [path.resolve(cliPackage, 'src', 'templates', '**', '*.ejs')],
|
||||
to: path.resolve(cliPackage, 'build', 'templates')
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin to mark all WebdriverIO scripts in `packages/webdriverio/src/scripts` as external
|
||||
*/
|
||||
export function externalScripts(): Plugin {
|
||||
const name = 'ExternalScripts'
|
||||
return {
|
||||
name,
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /\/scripts\// }, (args) => {
|
||||
return {
|
||||
path: args.path.replace('../../', './'),
|
||||
external: true,
|
||||
pluginName: name
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
130
infra/compiler/src/type-generation/index.ts
Normal file
130
infra/compiler/src/type-generation/index.ts
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import fs from 'node:fs'
|
||||
import url from 'node:url'
|
||||
import path from 'node:path'
|
||||
import camelCase from 'camelcase'
|
||||
import { type Plugin } from 'esbuild'
|
||||
|
||||
import { paramTypeMap, returnTypeMap } from './constants.js'
|
||||
import { PROTOCOLS } from '../../../../scripts/protocols.js'
|
||||
|
||||
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
|
||||
const TYPINGS_PATH = path.join(__dirname, '..', '..', '..', '..', 'packages', 'wdio-protocols', 'src', 'commands')
|
||||
|
||||
const INDENTATION = ' '.repeat(4)
|
||||
const EXAMPLE_INDENTATION = `${INDENTATION} * `
|
||||
const DEPRECATED_INDENTATION = `\n${INDENTATION} * @deprecated`
|
||||
const jsDocTemplate = `
|
||||
${INDENTATION}/**
|
||||
${INDENTATION} * {PROTOCOL} Protocol Command
|
||||
${INDENTATION} *
|
||||
${INDENTATION} * {DESCRIPTION}
|
||||
${INDENTATION} * @ref {REF}
|
||||
${INDENTATION} *{EXAMPLE}
|
||||
${INDENTATION} */`
|
||||
|
||||
export function generateTypes (): Plugin {
|
||||
return {
|
||||
name: 'generate-types',
|
||||
setup (build) {
|
||||
build.onStart(() => generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generate () {
|
||||
/**
|
||||
* create directory if not existing
|
||||
*/
|
||||
if (!fs.existsSync(TYPINGS_PATH)) {
|
||||
fs.mkdirSync(TYPINGS_PATH)
|
||||
}
|
||||
|
||||
for (const [protocolName, definition] of Object.entries(PROTOCOLS)) {
|
||||
if (protocolName === 'webdriverBidi') {
|
||||
continue
|
||||
}
|
||||
const interfaceName = protocolName.slice(0, 1).toUpperCase() + protocolName.slice(1)
|
||||
const customTypes = new Set()
|
||||
const lines = ['']
|
||||
|
||||
lines.push(`// ${protocolName} types`)
|
||||
lines.push(`export default interface ${interfaceName}Commands {`)
|
||||
|
||||
for (const methods of Object.values(definition)) {
|
||||
for (const description of Object.values(methods)) {
|
||||
const { command, parameters = [], variables = [], returns, ref, deprecated, examples } = description
|
||||
if (!ref) {
|
||||
throw new Error(`missing ref for command ${command} in ${protocolName}`)
|
||||
}
|
||||
const vars = variables
|
||||
// sessionId is handled by WebdriverIO for all protocol requests
|
||||
.filter((v) => v.name !== 'sessionId')
|
||||
// url params are always type of string
|
||||
.map((v) => `${v.name}: string`)
|
||||
const params = parameters.map((p, idx) => {
|
||||
const hasCustomType = (
|
||||
paramTypeMap[command as keyof typeof paramTypeMap] &&
|
||||
paramTypeMap[command as keyof typeof paramTypeMap][idx] &&
|
||||
paramTypeMap[command as keyof typeof paramTypeMap][idx].name === p.name
|
||||
)
|
||||
const paramType = hasCustomType
|
||||
? paramTypeMap[command as keyof typeof paramTypeMap][idx].type
|
||||
: p.type.toLowerCase()
|
||||
if (hasCustomType && Boolean(paramTypeMap[command as keyof typeof paramTypeMap][idx].requiresImport)) {
|
||||
customTypes.add(paramType)
|
||||
}
|
||||
return `${camelCase(p.name)}${p.required === false ? '?' : ''}: ${paramType}`
|
||||
})
|
||||
const varsAndParams = vars.concat(params)
|
||||
let returnValue = returns ? returns.type.toLowerCase() : 'void'
|
||||
returnValue = returnValue === '*' ? 'any' : returnValue
|
||||
if (returnTypeMap[command as keyof typeof returnTypeMap]) {
|
||||
returnValue = returnTypeMap[command as keyof typeof returnTypeMap]
|
||||
customTypes.add(returnTypeMap[command as keyof typeof returnTypeMap].replace('[]', ''))
|
||||
}
|
||||
if (returnValue === 'object') {
|
||||
returnValue = 'ProtocolCommandResponse'
|
||||
customTypes.add(returnValue)
|
||||
}
|
||||
|
||||
const jsDoc = jsDocTemplate
|
||||
.replace('{PROTOCOL}', interfaceName)
|
||||
.replace('{DESCRIPTION}', description.description || 'No description available, please see reference link.')
|
||||
.replace('{EXAMPLE}', (
|
||||
(examples || [])
|
||||
.map((example) => (
|
||||
`\n${EXAMPLE_INDENTATION}@example\n` +
|
||||
`${EXAMPLE_INDENTATION}\`\`\`js\n` +
|
||||
EXAMPLE_INDENTATION +
|
||||
`${example.map((l, i) => (i === 0
|
||||
? `${l}`
|
||||
: `${EXAMPLE_INDENTATION}${l.replace(/(\/\*\*|\s\*\s|\s\*\/)/, '// ')}`.trimEnd())
|
||||
).join('\n')}\n` +
|
||||
`${EXAMPLE_INDENTATION}` + '```'
|
||||
))
|
||||
.join(`\n${EXAMPLE_INDENTATION}`.trim())
|
||||
)
|
||||
)
|
||||
// Conditionally adds the '@deprecated' tag next to '{REF}' if 'deprecated' value is passed, otherwise leaves it unchanged.
|
||||
.replace('{REF}', deprecated ? `{REF}${DEPRECATED_INDENTATION} ${deprecated}` : '{REF}')
|
||||
.replace('{REF}', ref)
|
||||
lines.push(jsDoc)
|
||||
lines.push(`${INDENTATION}${command}(${varsAndParams.join(', ')}): Promise<${returnValue}>;`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* import missing protocol types
|
||||
*/
|
||||
if (customTypes.size) {
|
||||
lines.unshift(`import type { ${[...customTypes].join(', ')} } from '../types.js'`)
|
||||
}
|
||||
|
||||
lines.push('}')
|
||||
|
||||
fs.writeFileSync(path.join(TYPINGS_PATH, `${protocolName}.ts`), lines.join('\n'), 'utf8')
|
||||
console.log(` 🧩 Generated typings file for ${protocolName}`)
|
||||
}
|
||||
}
|
||||
13
infra/compiler/src/utils.ts
Normal file
13
infra/compiler/src/utils.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { builtinModules } from 'node:module'
|
||||
import type { PackageJson } from 'type-fest'
|
||||
|
||||
export function getExternal(pkg: PackageJson) {
|
||||
return [
|
||||
'virtual:*',
|
||||
...builtinModules,
|
||||
...builtinModules.map((mod) => `node:${mod}`),
|
||||
...Object.keys(pkg.dependencies || {}),
|
||||
...Object.keys(pkg.peerDependencies || {}),
|
||||
...Object.keys(pkg.optionalDependencies || {}),
|
||||
]
|
||||
}
|
||||
12
package.json
12
package.json
|
|
@ -6,7 +6,7 @@
|
|||
"scripts": {
|
||||
"create": "tsx ./scripts/generateSubPackage.ts",
|
||||
"backport": "tsx ./scripts/backport.ts",
|
||||
"build": "run-s clean:build generate compile copy",
|
||||
"build": "run-s clean:build generate compile:all",
|
||||
"changelog": "tsx ./scripts/changelog.ts",
|
||||
"ci": "run-s setup test test:e2e",
|
||||
"clean": "run-p clean:*",
|
||||
|
|
@ -18,11 +18,13 @@
|
|||
"clean:cache": "rimraf --glob .eslintcache",
|
||||
"clean:protocols": "rimraf --glob packages/wdio-protocols/src/commands",
|
||||
"clean:cddl": "rimraf --glob scripts/bidi/cddl",
|
||||
"compile": "tsx ./scripts/build.ts",
|
||||
"copy": "cd packages/wdio-cli && pnpm copy && cd ../../",
|
||||
"compile": "pnpm -r --filter=@wdio/compiler run build",
|
||||
"compile:all": "run-s compile:all:*",
|
||||
"compile:all:core": "pnpm -r --filter=@wdio/compiler run build -p @wdio/logger -p @wdio/types -p @wdio/globals -p @wdio/protocols -p @wdio/repl",
|
||||
"compile:all:main": "pnpm -r --filter=@wdio/compiler run build -p @wdio/utils -p @wdio/reporter -p @wdio/config -p webdriver -p webdriverio",
|
||||
"compile:all:all": "pnpm -r --filter=@wdio/compiler run build",
|
||||
"generate": "run-s generate:*",
|
||||
"generate:bidi": "tsx ./scripts/bidi/index.ts",
|
||||
"generate:typings": "tsx ./scripts/type-generation/generate-all-typings.ts",
|
||||
"link": "tsx ./scripts/link.ts",
|
||||
"pushReleaseTag": "tsx ./scripts/pushTags.ts",
|
||||
"setup": "run-s clean link build",
|
||||
|
|
@ -53,7 +55,7 @@
|
|||
"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",
|
||||
"watch": "tsx ./scripts/build.ts --watch",
|
||||
"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",
|
||||
"postinstall": "run-s postinstall:*",
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"name": "eslint-plugin-wdio-cjs",
|
||||
"type": "commonjs",
|
||||
"private": true
|
||||
}
|
||||
|
|
@ -5,19 +5,17 @@
|
|||
"author": "Christian Bromann <mail@bromann.dev>",
|
||||
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/eslint-plugin-wdio",
|
||||
"license": "MIT",
|
||||
"main": "./cjs/index.js",
|
||||
"main": "./build/index.cjs",
|
||||
"module": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
"import": {
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"default": "./build/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./build/index.d.ts",
|
||||
"default": "./cjs/index.js"
|
||||
"import": "./build/index.js",
|
||||
"require": "./build/index.cjs"
|
||||
}
|
||||
},
|
||||
"type": "module",
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const flatConfig = {
|
|||
},
|
||||
}
|
||||
|
||||
export = {
|
||||
export default {
|
||||
...index,
|
||||
configs: {
|
||||
'flat/recommended': flatConfig,
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"extends": "./tsconfig.prod.json",
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "Node",
|
||||
"outDir": "./cjs",
|
||||
"declaration": false,
|
||||
"declarationMap": false
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"name": "@wdio/allure-reporter-cjs",
|
||||
"type": "commonjs",
|
||||
"private": true
|
||||
}
|
||||
|
|
@ -24,15 +24,12 @@
|
|||
"module": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"require": "./cjs/common/api.js"
|
||||
},
|
||||
"./cjs/common/api.js"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"requireSource": "./src/common/api.ts",
|
||||
"require": "./build/index.cjs"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"extends": "./tsconfig.prod.json",
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "Node",
|
||||
"outDir": "./cjs",
|
||||
"declaration": false,
|
||||
"declarationMap": false
|
||||
},
|
||||
"include": [
|
||||
"src/common",
|
||||
"src/constants",
|
||||
]
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -28,8 +28,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -25,11 +25,39 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js"
|
||||
},
|
||||
"./stencil": {
|
||||
"importSource": "./src/browser/integrations/stencil.ts",
|
||||
"import": "./build/browser/integrations/stencil.js",
|
||||
"types": "./stencil/index.d.ts"
|
||||
"types": "./build/browser/integrations/stencil.d.ts"
|
||||
},
|
||||
"./driver": {
|
||||
"browserSource": "./src/browser/driver.ts",
|
||||
"browser": "./build/browser/driver.js",
|
||||
"types": "./build/browser/driver.d.ts"
|
||||
},
|
||||
"./mock": {
|
||||
"browserSource": "./src/browser/mock.ts",
|
||||
"browser": "./build/browser/mock.js",
|
||||
"types": "./build/browser/mock.d.ts"
|
||||
},
|
||||
"./setup": {
|
||||
"browserSource": "./src/browser/setup.ts",
|
||||
"browser": "./build/browser/setup.js",
|
||||
"types": "./build/browser/setup.d.ts"
|
||||
},
|
||||
"./spy": {
|
||||
"browserSource": "./src/browser/spy.ts",
|
||||
"browser": "./build/browser/spy.js",
|
||||
"types": "./build/browser/spy.d.ts"
|
||||
},
|
||||
"./expect": {
|
||||
"browserSource": "./src/browser/expect.ts",
|
||||
"browser": "./build/browser/expect.js",
|
||||
"types": "./build/browser/expect.d.ts"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
|
|
@ -65,16 +93,18 @@
|
|||
"webdriver": "workspace:*",
|
||||
"webdriverio": "workspace:*"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "rimraf node_modules/@wdio/config node_modules/@wdio/repl node_modules/@wdio/utils"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/istanbul-lib-coverage": "^2.0.6",
|
||||
"@types/istanbul-lib-report": "^3.0.3",
|
||||
"@types/istanbul-reports": "^3.0.4",
|
||||
"esbuild": "^0.21.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@nuxt/kit": "^3.12.4",
|
||||
"@stencil/core": "^4.20.0",
|
||||
"unimport": "^3.10.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,4 +31,5 @@ export const type = 'browser'
|
|||
export const sync = () => {}
|
||||
export const locateChrome = () => {}
|
||||
export const locateFirefox = () => {}
|
||||
export const locateApp = () => {}
|
||||
export default () => {}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export async function optimizeForStencil(rootDir: string) {
|
|||
|
||||
async function stencilVitePlugin(rootDir: string): Promise<Plugin> {
|
||||
const { transpileSync, ts } = await import('@stencil/core/compiler/stencil.js')
|
||||
const stencilHelperPath = path.resolve(__dirname, '..', '..', 'browser', 'integrations', 'stencil.js')
|
||||
const stencilHelperPath = path.resolve(__dirname, 'browser', 'integrations', 'stencil.js')
|
||||
return {
|
||||
name: 'wdio-stencil',
|
||||
enforce: 'pre',
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ const POLYFILLS = [
|
|||
...builtinModules.map((m) => `node:${m}`)
|
||||
]
|
||||
export function testrunner(options: WebdriverIO.BrowserRunnerOptions): Plugin[] {
|
||||
const browserModules = path.resolve(__dirname, '..', '..', 'browser')
|
||||
const browserModules = path.resolve(__dirname, 'browser')
|
||||
const automationProtocolPath = `/@fs${url.pathToFileURL(path.resolve(browserModules, 'driver.js')).pathname}`
|
||||
const mockModulePath = path.resolve(browserModules, 'mock.js')
|
||||
const setupModulePath = path.resolve(browserModules, 'setup.js')
|
||||
|
|
@ -91,6 +91,11 @@ export function testrunner(options: WebdriverIO.BrowserRunnerOptions): Plugin[]
|
|||
return wdioExpectModulePath
|
||||
}
|
||||
|
||||
if (id === '@wdio/logger') {
|
||||
const newId = url.fileURLToPath(await resolve(id, import.meta.url))
|
||||
return path.resolve(path.dirname(newId), 'browser.js')
|
||||
}
|
||||
|
||||
/**
|
||||
* make sure WDIO imports are resolved properly as ESM module
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,32 +26,6 @@ export async function getTemplate(options: WebdriverIO.BrowserRunnerOptions, env
|
|||
delete env.config.runner
|
||||
}
|
||||
|
||||
let vueDeps = ''
|
||||
if (options.preset === 'vue') {
|
||||
try {
|
||||
const vueDir = path.dirname(url.fileURLToPath(await resolve('vue', `${rootFileUrl}/node_modules`)))
|
||||
const vueScript = (await fs.readFile(path.join(vueDir, 'dist', 'vue.global.prod.js'), 'utf-8')).toString()
|
||||
vueDeps += /*html*/`
|
||||
<script type="module">
|
||||
${vueScript}
|
||||
window.Vue = Vue
|
||||
</script>`
|
||||
const vueCompilerDir = path.dirname(url.fileURLToPath(await resolve('@vue/compiler-dom', `${rootFileUrl}/node_modules`)))
|
||||
const vueCompilerScript = (await fs.readFile(path.join(vueCompilerDir, 'dist', 'compiler-dom.global.prod.js'))).toString()
|
||||
vueDeps += /*html*/`
|
||||
<script type="module">
|
||||
${vueCompilerScript}
|
||||
window.VueCompilerDOM = VueCompilerDOM
|
||||
</script>`
|
||||
} catch (err: any) {
|
||||
throw new Error(
|
||||
`Fail to set-up Vue environment: ${err.message}\n\n` +
|
||||
'Make sure you have "vue" and "@vue/compiler-dom" installed as dependencies!\n' +
|
||||
`Error: ${err.stack}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let sourceMapScript = ''
|
||||
let sourceMapSetupCommand = ''
|
||||
try {
|
||||
|
|
@ -141,7 +115,6 @@ export async function getTemplate(options: WebdriverIO.BrowserRunnerOptions, env
|
|||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
${vueDeps}
|
||||
</head>
|
||||
<body>
|
||||
<mocha-framework spec="${spec}" ${isHeadless ? 'style="display: none"' : ''}></mocha-framework>
|
||||
|
|
|
|||
|
|
@ -139,15 +139,6 @@ exports[`getTemplate > renders template correctly 1`] = `
|
|||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="module">
|
||||
some code
|
||||
window.Vue = Vue
|
||||
</script>
|
||||
<script type="module">
|
||||
some code
|
||||
window.VueCompilerDOM = VueCompilerDOM
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<mocha-framework spec="/spec.js" style="display: none"></mocha-framework>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import os from 'node:os'
|
||||
import url from 'node:url'
|
||||
import path from 'node:path'
|
||||
import fs from 'node:fs/promises'
|
||||
|
||||
import { describe, it, vi, expect } from 'vitest'
|
||||
import { resolve } from 'import-meta-resolve'
|
||||
|
|
@ -29,12 +28,6 @@ vi.mock('fakeDep', () => ({
|
|||
// skip for Windows
|
||||
if (os.platform() !== 'win32') {
|
||||
describe('getTemplate', () => {
|
||||
it('fails if vue helpers are not installed', async () => {
|
||||
vi.mocked(resolve).mockRejectedValue(new Error('not there'))
|
||||
await expect(getTemplate({ preset: 'vue' }, { config: {} } as any, ''))
|
||||
.rejects.toThrow(/Fail to set-up Vue environment/)
|
||||
})
|
||||
|
||||
it('renders template correctly', async () => {
|
||||
vi.mocked(resolve).mockResolvedValue('file:///foo/bar/vue')
|
||||
/**
|
||||
|
|
@ -44,8 +37,7 @@ if (os.platform() !== 'win32') {
|
|||
process.env.CI = '1'
|
||||
}
|
||||
const p: any = { env: { some: 'env' }, cwd: () => '/some/cwd' }
|
||||
expect(await getTemplate({ preset: 'vue' }, { config: {} } as any, '/spec.js', p)).toMatchSnapshot()
|
||||
expect(fs.readFile).toBeCalledTimes(2)
|
||||
expect(await getTemplate({ preset: 'lit' }, { config: {} } as any, '/spec.js', p)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@
|
|||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"types": ["@wdio/globals/types"]
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"types": ["@wdio/globals/types"]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types",
|
||||
"../wdio-globals/types"
|
||||
]
|
||||
}
|
||||
|
|
@ -25,8 +25,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { BrowserstackConfig } from './types.js'
|
||||
import { createRequire } from 'node:module'
|
||||
const require = createRequire(import.meta.url)
|
||||
const { version: bstackServiceVersion } = require('../package.json')
|
||||
import pkg from '../package.json' assert { type: 'json' }
|
||||
|
||||
const bstackServiceVersion = pkg.version
|
||||
|
||||
export const BROWSER_DESCRIPTION = [
|
||||
'device',
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"types": ["@wdio/globals/types"]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -11,9 +11,6 @@
|
|||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"scripts": {
|
||||
"copy": "copyfiles -u 1 -V \"src/templates/**/*\" ./build/"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/webdriverio/webdriverio.git",
|
||||
|
|
@ -33,15 +30,12 @@
|
|||
"module": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"require": "./build/index.cjs"
|
||||
},
|
||||
"./build/index.cjs"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"requireSource": "./src/index.cts",
|
||||
"require": "./build/index.cjs"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import fs from 'node:fs/promises'
|
||||
import fss from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
import inquirer from 'inquirer'
|
||||
|
|
@ -15,7 +16,13 @@ import {
|
|||
} from '../utils.js'
|
||||
import type { ConfigCommandArguments, ParsedAnswers } from '../types.js'
|
||||
|
||||
const hasYarnLock = await fs.access('yarn.lock').then(() => true, () => false)
|
||||
let hasYarnLock = false
|
||||
try {
|
||||
fss.accessSync('yarn.lock')
|
||||
hasYarnLock = true
|
||||
} catch {
|
||||
hasYarnLock = false
|
||||
}
|
||||
|
||||
export const command = 'config'
|
||||
export const desc = 'Initialize WebdriverIO and setup configuration in your current project.'
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/// <reference types="@wdio/globals/types" />
|
||||
import pickBy from 'lodash.pickby'
|
||||
import { remote } from 'webdriverio'
|
||||
import type { Argv, Options } from 'yargs'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import fs from 'node:fs/promises'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { createRequire } from 'node:module'
|
||||
import { HOOK_DEFINITION } from '@wdio/utils'
|
||||
import type { Options, Services, Reporters } from '@wdio/types'
|
||||
|
||||
|
|
@ -12,10 +11,9 @@ import {
|
|||
detectPackageManager,
|
||||
} from './utils.js'
|
||||
import type { Questionnair } from './types.js'
|
||||
import pkgJSON from '../package.json' with { type: 'json' }
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
export const pkg = require('../package.json')
|
||||
|
||||
export const pkg = pkgJSON
|
||||
export const CLI_EPILOGUE = `Documentation: https://webdriver.io\n@wdio/cli (v${pkg.version})`
|
||||
|
||||
export const CONFIG_HELPER_INTRO = `
|
||||
|
|
@ -24,6 +22,7 @@ export const CONFIG_HELPER_INTRO = `
|
|||
===============================
|
||||
`
|
||||
|
||||
export const SUPPORTED_COMMANDS = ['run', 'install', 'config', 'repl']
|
||||
export const PMs = ['npm', 'yarn', 'pnpm', 'bun'] as const
|
||||
export const SUPPORTED_CONFIG_FILE_EXTENSION = ['js', 'ts', 'mjs', 'mts', 'cjs', 'cts']
|
||||
export const configHelperSuccessMessage = ({ projectRootDir, runScript, extraInfo = '' }: { projectRootDir: string, runScript: string, extraInfo: string }) => `
|
||||
|
|
@ -229,19 +228,19 @@ function getTestingPurpose (answers: Questionnair) {
|
|||
return convertPackageHashToObject(answers.runner).purpose as 'e2e' | 'electron' | 'component' | 'vscode' | 'macos'
|
||||
}
|
||||
|
||||
export const isNuxtProject = await Promise.all(
|
||||
[
|
||||
path.join(process.cwd(), 'nuxt.config.js'),
|
||||
path.join(process.cwd(), 'nuxt.config.ts'),
|
||||
path.join(process.cwd(), 'nuxt.config.mjs'),
|
||||
path.join(process.cwd(), 'nuxt.config.mts')
|
||||
].map(
|
||||
(p) => fs.access(p).then(() => true, () => false)
|
||||
)
|
||||
).then(
|
||||
(res) => res.some(Boolean),
|
||||
() => false
|
||||
)
|
||||
export const isNuxtProject = [
|
||||
path.join(process.cwd(), 'nuxt.config.js'),
|
||||
path.join(process.cwd(), 'nuxt.config.ts'),
|
||||
path.join(process.cwd(), 'nuxt.config.mjs'),
|
||||
path.join(process.cwd(), 'nuxt.config.mts')
|
||||
].map((p) => {
|
||||
try {
|
||||
fs.accessSync(p)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}).some(Boolean)
|
||||
|
||||
function selectDefaultService (serviceNames: string | string[]) {
|
||||
serviceNames = Array.isArray(serviceNames) ? serviceNames : [serviceNames]
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ class Launcher {
|
|||
args: any = {},
|
||||
isWatchMode = false
|
||||
) {
|
||||
this.#esmLauncher = import('./launcher.js').then(
|
||||
({ default: Launcher }) => new Launcher(configFilePath, args, isWatchMode))
|
||||
this.#esmLauncher = import('./index.js').then(
|
||||
({ Launcher }) => new Launcher(configFilePath, args, isWatchMode))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import fs from 'node:fs'
|
||||
import url from 'node:url'
|
||||
import path from 'node:path'
|
||||
|
||||
import yargs from 'yargs'
|
||||
|
|
@ -7,11 +5,9 @@ import { hideBin } from 'yargs/helpers'
|
|||
|
||||
import { commands } from './commands/index.js'
|
||||
import { handler, cmdArgs } from './commands/run.js'
|
||||
import { CLI_EPILOGUE, pkg } from './constants.js'
|
||||
import { CLI_EPILOGUE, pkg, SUPPORTED_COMMANDS } from './constants.js'
|
||||
import type { RunCommandArguments } from './types.js'
|
||||
|
||||
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
|
||||
|
||||
const DEFAULT_CONFIG_FILENAME = 'wdio.conf.js'
|
||||
const DESCRIPTION = [
|
||||
'The `wdio` command allows you run and manage your WebdriverIO test suite.',
|
||||
|
|
@ -26,7 +22,6 @@ const DESCRIPTION = [
|
|||
]
|
||||
|
||||
export default async function run() {
|
||||
const commandDir = path.join(__dirname, 'commands')
|
||||
const argv = yargs(hideBin(process.argv))
|
||||
.command(commands)
|
||||
.example('wdio run wdio.conf.js --suite foobar', 'Run suite on testsuite "foobar"')
|
||||
|
|
@ -58,11 +53,7 @@ export default async function run() {
|
|||
* we don't have to check that again here.
|
||||
*/
|
||||
const params = await argv.parse()
|
||||
const supportedCommands = fs
|
||||
.readdirSync(commandDir)
|
||||
.map((file) => file.slice(0, -3))
|
||||
|
||||
if (!params._ || params._.find((param: string) => supportedCommands.includes(param))) {
|
||||
if (!params._ || params._.find((param: string) => SUPPORTED_COMMANDS.includes(param))) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ export async function getCapabilities(arg: ReplCommandArguments) {
|
|||
// multiremote
|
||||
(requiredCaps as Capabilities.RequestedMultiremoteCapabilities)[arg.capabilities]
|
||||
)
|
||||
const requiredW3CCaps = pickBy(requiredCaps, (_, key) => CAPABILITY_KEYS.includes(key) || key.includes(':'))
|
||||
const requiredW3CCaps = pickBy(requiredCaps, (_: never, key: string) => CAPABILITY_KEYS.includes(key) || key.includes(':'))
|
||||
if (!Object.keys(requiredW3CCaps).length) {
|
||||
throw Error(`No capability found in given config file with the provided capability indexed/named property: ${arg.capabilities}. Please check the capability in your wdio config file.`)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@
|
|||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"types": ["@wdio/globals/types"]
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"types": ["@wdio/globals/types"]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types",
|
||||
"src/cjs/package.json"
|
||||
]
|
||||
}
|
||||
|
|
@ -24,8 +24,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -13,10 +13,10 @@
|
|||
"types": "./build/index.d.ts"
|
||||
},
|
||||
"./node": {
|
||||
"importSource": "./src/node/index.ts",
|
||||
"import": "./build/node/index.js",
|
||||
"types": "./build/node/index.d.ts"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ export default class ConfigParser {
|
|||
/**
|
||||
* return capabilities
|
||||
*/
|
||||
getCapabilities(i?: number) {
|
||||
getCapabilities(i?: number): Capabilities.TestrunnerCapabilities | Capabilities.RequestedStandaloneCapabilities {
|
||||
if (!this.#isInitialised) {
|
||||
throw new Error('ConfigParser was not initialized, call "await config.initialize()" first!')
|
||||
}
|
||||
|
|
@ -427,7 +427,7 @@ export default class ConfigParser {
|
|||
return this._capabilities[i]
|
||||
}
|
||||
|
||||
return this._capabilities
|
||||
return this._capabilities!
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -25,15 +25,16 @@
|
|||
"type": "module",
|
||||
"module": "./build/index.js",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"require": "./build/index.cjs"
|
||||
},
|
||||
"./build/index.cjs"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"requireSource": "./src/index.cts",
|
||||
"require": "./build/index.cjs"
|
||||
},
|
||||
"./formatter": {
|
||||
"source": "./src/cucumberFormatter.ts",
|
||||
"import": "./build/cucumberFormatter.js"
|
||||
}
|
||||
},
|
||||
"types": "./build/index.d.ts",
|
||||
"typeScriptVersion": "3.8.3",
|
||||
|
|
@ -45,6 +46,7 @@
|
|||
"@wdio/logger": "workspace:*",
|
||||
"@wdio/types": "workspace:*",
|
||||
"@wdio/utils": "workspace:*",
|
||||
"import-meta-resolve": "^4.1.0",
|
||||
"glob": "^10.2.2",
|
||||
"is-glob": "^4.0.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ export const FILE_PROTOCOL = 'file://'
|
|||
const uuidFn = IdGenerator.uuid()
|
||||
const log = logger('@wdio/cucumber-framework')
|
||||
const require = createRequire(import.meta.url)
|
||||
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
|
||||
|
||||
function getResultObject(
|
||||
world: Cucumber.ITestCaseHookParameter
|
||||
|
|
@ -87,7 +88,7 @@ class CucumberAdapter {
|
|||
private _reporter: EventEmitter,
|
||||
private _eventEmitter: EventEmitter,
|
||||
private _generateSkipTags: boolean = true,
|
||||
private _cucumberFormatter: string = url.pathToFileURL(path.resolve(url.fileURLToPath(import.meta.url), '..', 'cucumberFormatter.js')).href
|
||||
private _cucumberFormatter: string = url.pathToFileURL(path.resolve(__dirname, 'cucumberFormatter.js')).href
|
||||
) {
|
||||
this._eventEmitter = new EventEmitter()
|
||||
this._cucumberOpts = Object.assign(
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ export function generateSkipTagsFromCapabilities(capabilities: Capabilities.Reso
|
|||
const pos = splitItem.indexOf('=')
|
||||
if (pos > 0) {
|
||||
try {
|
||||
acc[splitItem.substring(0, pos)] = eval(
|
||||
acc[splitItem.substring(0, pos)] = (0, eval)(
|
||||
splitItem.substring(pos + 1)
|
||||
)
|
||||
} catch (err: any) {
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types",
|
||||
"src/cjs/package.json"
|
||||
]
|
||||
}
|
||||
|
|
@ -23,8 +23,10 @@
|
|||
},
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -31,8 +31,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
src
|
||||
tests
|
||||
tsconfig.json
|
||||
tsconfig.prod.json
|
||||
tsconfig.cjs.json
|
||||
tsconfig.prod.jsontsconfig.cjs.json
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"name": "@wdio/globals-cjs",
|
||||
"type": "commonjs",
|
||||
"private": true
|
||||
}
|
||||
|
|
@ -5,20 +5,18 @@
|
|||
"author": "Christian Bromann <mail@bromann.dev>",
|
||||
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-globals",
|
||||
"license": "MIT",
|
||||
"main": "./cjs/index.js",
|
||||
"main": "./build/index.cjs",
|
||||
"type": "module",
|
||||
"module": "./build/index.js",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"require": "./cjs/index.js"
|
||||
},
|
||||
"./cjs/index.js"
|
||||
],
|
||||
"./types": "./types.d.ts",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"require": "./build/index.cjs"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./types.d.ts"
|
||||
}
|
||||
},
|
||||
"types": "./build/index.d.ts",
|
||||
"typeScriptVersion": "3.8.3",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ type SupportedGlobals = 'browser' | 'driver' | 'multiremotebrowser' | '$' | '$$'
|
|||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var _wdioGlobals: Map<SupportedGlobals, any>
|
||||
namespace WebdriverIO {
|
||||
interface Browser {}
|
||||
interface Element {}
|
||||
interface MultiRemoteBrowser {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"extends": "./tsconfig.prod.json",
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "Node",
|
||||
"outDir": "./cjs",
|
||||
"declaration": false,
|
||||
"declarationMap": false
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -8,8 +8,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -25,12 +25,14 @@
|
|||
"type": "module",
|
||||
"exports": {
|
||||
"./mergeResults": {
|
||||
"types": "./build/mergeResults.d.ts",
|
||||
"source": "./src/mergeResults.ts",
|
||||
"import": "./build/mergeResults.js",
|
||||
"require": "./build/mergeResults.cjs"
|
||||
},
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts"
|
||||
}
|
||||
},
|
||||
"types": "./build/index.d.ts",
|
||||
"typeScriptVersion": "3.8.3",
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
module.exports = async function (...args: any[]) {
|
||||
const mergeResults = (await import('./mergeResults.js')).default
|
||||
return mergeResults(...args)
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types",
|
||||
"src/cjs/package.json"
|
||||
]
|
||||
}
|
||||
|
|
@ -26,8 +26,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -33,8 +33,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"types": ["@wdio/globals/types"]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -25,8 +25,14 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js"
|
||||
},
|
||||
"./run": {
|
||||
"source": "./src/run.ts",
|
||||
"import": "./build/run.js"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -7,8 +7,15 @@
|
|||
"license": "MIT",
|
||||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"main": "./build/index.cjs",
|
||||
"browser": "./build/browser.js",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
".": {
|
||||
"browser": "./build/browser.js",
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
"browserSource": "./src/browser.ts"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
const LOG_METHODS = ['error', 'warn', 'info', 'debug', 'trace', 'silent']
|
||||
|
||||
export type { Logger } from './index.js'
|
||||
|
||||
/**
|
||||
* This implementation of the Logger package is a simple adptation to run it within
|
||||
* a browser environment.
|
||||
*/
|
||||
export default function getLogger (component: string) {
|
||||
return LOG_METHODS.reduce((acc: Console, cur: string): Console => {
|
||||
const prop = cur as keyof Console
|
||||
|
|
@ -1,25 +1,232 @@
|
|||
/* istanbul ignore file */
|
||||
import fs from 'node:fs'
|
||||
import util from 'node:util'
|
||||
|
||||
import type loggerType from './node.js'
|
||||
export type { Logger } from './node.js'
|
||||
import log from 'loglevel'
|
||||
import type { ColorName } from 'chalk'
|
||||
import chalk from 'chalk'
|
||||
import prefix from 'loglevel-plugin-prefix'
|
||||
import ansiStrip from 'strip-ansi'
|
||||
|
||||
/**
|
||||
* environment check to allow to use this package in a web context
|
||||
*/
|
||||
// By default, import the web code using a literal require, so that in webpack
|
||||
// contexts, it will always be bundled
|
||||
let mode = await import('./web.js') as any
|
||||
prefix.reg(log)
|
||||
|
||||
// Then, if we're in a Node.js context, require the node version of this module
|
||||
// using a variable, so that it will _not_ be included in a bundle, either
|
||||
// during compilation or execution
|
||||
if (typeof process !== 'undefined' && typeof process.release !== 'undefined' && process.release.name === 'node') {
|
||||
const nodeMode = './node.js'
|
||||
mode = await import(nodeMode)
|
||||
const DEFAULT_LEVEL = process.env.WDIO_DEBUG
|
||||
? 'trace'
|
||||
: 'info'
|
||||
const COLORS: Record<string, ColorName> = {
|
||||
error: 'red',
|
||||
warn: 'yellow',
|
||||
info: 'cyanBright',
|
||||
debug: 'green',
|
||||
trace: 'cyan',
|
||||
progress: 'magenta'
|
||||
}
|
||||
|
||||
// The net result will be that in a Node context, we'll have required both
|
||||
// files but will use the correct one, and in the web context, we'll have only
|
||||
// required the web file, thus ensuring that the Node file and related
|
||||
// dependencies will not be bundled inadvertently.
|
||||
export default mode.default as typeof loggerType
|
||||
const matches = {
|
||||
COMMAND: 'COMMAND',
|
||||
BIDICOMMAND: 'BIDI COMMAND',
|
||||
DATA: 'DATA',
|
||||
RESULT: 'RESULT',
|
||||
BIDIRESULT: 'BIDI RESULT'
|
||||
}
|
||||
|
||||
const SERIALIZERS = [{
|
||||
/**
|
||||
* display error stack
|
||||
*/
|
||||
matches: (err: any) => err instanceof Error,
|
||||
serialize: (err: any) => err.stack
|
||||
}, {
|
||||
/**
|
||||
* color commands blue
|
||||
*/
|
||||
matches: (log: string) => log === matches.COMMAND || log === matches.BIDICOMMAND,
|
||||
serialize: (log: string) => chalk.magenta(log)
|
||||
}, {
|
||||
/**
|
||||
* color data yellow
|
||||
*/
|
||||
matches: (log: string) => log === matches.DATA,
|
||||
serialize: (log: string) => chalk.yellow(log)
|
||||
}, {
|
||||
/**
|
||||
* color result cyan
|
||||
*/
|
||||
matches: (log: string) => log === matches.RESULT || log === matches.BIDIRESULT,
|
||||
serialize: (log: string) => chalk.cyan(log)
|
||||
}]
|
||||
|
||||
interface LoggerInterface extends log.Logger {
|
||||
progress(...msg: any[]): void;
|
||||
}
|
||||
|
||||
interface Loggers {
|
||||
[name: string]: LoggerInterface
|
||||
}
|
||||
|
||||
const loggers: Loggers = log.getLoggers() as Loggers
|
||||
let logLevelsConfig: Record<string, log.LogLevelDesc> = {}
|
||||
const logCache = new Set()
|
||||
let logFile: fs.WriteStream | null
|
||||
|
||||
const originalFactory = log.methodFactory
|
||||
const wdioLoggerMethodFactory = function (this: log.Logger, methodName: log.LogLevelNames, logLevel: log.LogLevelNumbers, loggerName: string) {
|
||||
const rawMethod = originalFactory(methodName, logLevel, loggerName)
|
||||
return (...args: string[]) => {
|
||||
/**
|
||||
* create logFile lazily
|
||||
*/
|
||||
if (!logFile && process.env.WDIO_LOG_PATH) {
|
||||
logFile = fs.createWriteStream(process.env.WDIO_LOG_PATH)
|
||||
}
|
||||
|
||||
/**
|
||||
* split `prefixer: value` sting to `prefixer: ` and `value`
|
||||
* so that SERIALIZERS can match certain string
|
||||
*/
|
||||
const match = Object.values(matches).filter(x => args[0].endsWith(`: ${x}`))[0]
|
||||
if (match) {
|
||||
const prefixStr = args.shift()!.slice(0, -match.length - 1)
|
||||
args.unshift(prefixStr, match)
|
||||
}
|
||||
|
||||
args = args.map((arg) => {
|
||||
for (const s of SERIALIZERS) {
|
||||
if (s.matches(arg)) {
|
||||
return s.serialize(arg)
|
||||
}
|
||||
}
|
||||
return arg
|
||||
})
|
||||
|
||||
const logText = ansiStrip(`${util.format.apply(this, args as [format: string, ...params: string[]])}\n`)
|
||||
if (logFile && logFile.writable) {
|
||||
/**
|
||||
* empty logging cache if stuff got logged before
|
||||
*/
|
||||
if (logCache.size) {
|
||||
logCache.forEach((log) => {
|
||||
if (logFile) {
|
||||
logFile.write(log)
|
||||
}
|
||||
})
|
||||
logCache.clear()
|
||||
}
|
||||
|
||||
if (!logsContainInitPackageError(logText)) {
|
||||
return logFile.write(logText)
|
||||
}
|
||||
// If we get Error during init of integration packages, write logs to both "outputDir" and the terminal
|
||||
logFile.write(logText)
|
||||
}
|
||||
|
||||
logCache.add(logText)
|
||||
rawMethod(...args)
|
||||
}
|
||||
}
|
||||
|
||||
const progress = function (this: any, data: string) {
|
||||
if (process.stdout.isTTY && this.getLevel() <= log.levels.INFO) {
|
||||
const level = 'progress'
|
||||
const timestampFormatter = chalk.gray(new Date().toISOString())
|
||||
const levelFormatter = chalk[COLORS[level]](level.toUpperCase())
|
||||
const nameFormatter = chalk.whiteBright(this.name)
|
||||
const _data = data.length > 0 ? `${timestampFormatter} ${levelFormatter} ${nameFormatter}: ${data}` : '\r\x1b[K\x1b[?25h'
|
||||
process.stdout.write('\u001B[?25l') // Disable cursor in terminal
|
||||
process.stdout.write(`${_data}\r`)
|
||||
}
|
||||
}
|
||||
|
||||
export default function getLogger (name: string) {
|
||||
/**
|
||||
* check if logger was already initiated
|
||||
*/
|
||||
if (loggers[name]) {
|
||||
return loggers[name]
|
||||
}
|
||||
|
||||
let logLevel: log.LogLevelDesc = (process.env.WDIO_LOG_LEVEL || DEFAULT_LEVEL) as log.LogLevelDesc
|
||||
const logLevelName = getLogLevelName(name)
|
||||
if (logLevelsConfig[logLevelName]) {
|
||||
logLevel = logLevelsConfig[logLevelName]
|
||||
}
|
||||
|
||||
loggers[name] = log.getLogger(name) as LoggerInterface
|
||||
loggers[name].setLevel(logLevel)
|
||||
loggers[name].methodFactory = wdioLoggerMethodFactory
|
||||
loggers[name].progress = progress
|
||||
prefix.apply(loggers[name], {
|
||||
template: '%t %l %n:',
|
||||
timestampFormatter: (date) => chalk.gray(date.toISOString()),
|
||||
levelFormatter: (level: string) => chalk[COLORS[level]](level.toUpperCase()),
|
||||
nameFormatter: (name) => chalk.whiteBright(name)
|
||||
})
|
||||
return loggers[name]
|
||||
}
|
||||
/**
|
||||
* Wait for writable stream to be flushed.
|
||||
* Calling this prevents part of the logs in the very env to be lost.
|
||||
*/
|
||||
getLogger.waitForBuffer = async () => new Promise<void>(resolve => {
|
||||
// @ts-ignore
|
||||
if (logFile && Array.isArray(logFile.writableBuffer) && logFile.writableBuffer.length !== 0) {
|
||||
return setTimeout(async () => {
|
||||
await getLogger.waitForBuffer()
|
||||
resolve()
|
||||
}, 20)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
getLogger.setLevel = (name: string, level: log.LogLevelDesc) => loggers[name].setLevel(level)
|
||||
getLogger.clearLogger = () => {
|
||||
if (logFile) {
|
||||
logFile.end()
|
||||
}
|
||||
logFile = null
|
||||
}
|
||||
getLogger.setLogLevelsConfig = (logLevels: Record<string, log.LogLevelDesc> = {}, wdioLogLevel: log.LogLevelDesc = DEFAULT_LEVEL) => {
|
||||
/**
|
||||
* set log level
|
||||
*/
|
||||
if (process.env.WDIO_LOG_LEVEL === undefined) {
|
||||
process.env.WDIO_LOG_LEVEL = wdioLogLevel as string
|
||||
}
|
||||
|
||||
logLevelsConfig = {}
|
||||
|
||||
/**
|
||||
* build logLevelsConfig object
|
||||
*/
|
||||
Object.entries(logLevels).forEach(([logName, logLevel]) => {
|
||||
const logLevelName = getLogLevelName(logName)
|
||||
logLevelsConfig[logLevelName] = logLevel
|
||||
})
|
||||
|
||||
/**
|
||||
* set log level for each logger
|
||||
*/
|
||||
Object.keys(loggers).forEach(logName => {
|
||||
const logLevelName = getLogLevelName(logName)
|
||||
|
||||
/**
|
||||
* either apply log level from logLevels object or use global logLevel
|
||||
*/
|
||||
const logLevel = typeof logLevelsConfig[logLevelName] !== 'undefined' ? logLevelsConfig[logLevelName] : process.env.WDIO_LOG_LEVEL as log.LogLevelDesc
|
||||
|
||||
loggers[logName].setLevel(logLevel)
|
||||
})
|
||||
}
|
||||
const getLogLevelName = (logName: string) => logName.split(':').shift() as log.LogLevelDesc
|
||||
|
||||
export type Logger = LoggerInterface
|
||||
|
||||
function logsContainInitPackageError(logText: string) {
|
||||
return ERROR_LOG_VALIDATOR.every(pattern => logText.includes(pattern))
|
||||
}
|
||||
|
||||
const ERROR_LOG_VALIDATOR = [
|
||||
'Couldn\'t find plugin',
|
||||
'neither as wdio scoped package',
|
||||
'nor as community package',
|
||||
'Please make sure you have it installed'
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,232 +0,0 @@
|
|||
import fs from 'node:fs'
|
||||
import util from 'node:util'
|
||||
|
||||
import log from 'loglevel'
|
||||
import type { ColorName } from 'chalk'
|
||||
import chalk from 'chalk'
|
||||
import prefix from 'loglevel-plugin-prefix'
|
||||
import ansiStrip from 'strip-ansi'
|
||||
|
||||
prefix.reg(log)
|
||||
|
||||
const DEFAULT_LEVEL = process.env.WDIO_DEBUG
|
||||
? 'trace'
|
||||
: 'info'
|
||||
const COLORS: Record<string, ColorName> = {
|
||||
error: 'red',
|
||||
warn: 'yellow',
|
||||
info: 'cyanBright',
|
||||
debug: 'green',
|
||||
trace: 'cyan',
|
||||
progress: 'magenta'
|
||||
}
|
||||
|
||||
const matches = {
|
||||
COMMAND: 'COMMAND',
|
||||
BIDICOMMAND: 'BIDI COMMAND',
|
||||
DATA: 'DATA',
|
||||
RESULT: 'RESULT',
|
||||
BIDIRESULT: 'BIDI RESULT'
|
||||
}
|
||||
|
||||
const SERIALIZERS = [{
|
||||
/**
|
||||
* display error stack
|
||||
*/
|
||||
matches: (err: any) => err instanceof Error,
|
||||
serialize: (err: any) => err.stack
|
||||
}, {
|
||||
/**
|
||||
* color commands blue
|
||||
*/
|
||||
matches: (log: string) => log === matches.COMMAND || log === matches.BIDICOMMAND,
|
||||
serialize: (log: string) => chalk.magenta(log)
|
||||
}, {
|
||||
/**
|
||||
* color data yellow
|
||||
*/
|
||||
matches: (log: string) => log === matches.DATA,
|
||||
serialize: (log: string) => chalk.yellow(log)
|
||||
}, {
|
||||
/**
|
||||
* color result cyan
|
||||
*/
|
||||
matches: (log: string) => log === matches.RESULT || log === matches.BIDIRESULT,
|
||||
serialize: (log: string) => chalk.cyan(log)
|
||||
}]
|
||||
|
||||
interface LoggerInterface extends log.Logger {
|
||||
progress(...msg: any[]): void;
|
||||
}
|
||||
|
||||
interface Loggers {
|
||||
[name: string]: LoggerInterface
|
||||
}
|
||||
|
||||
const loggers: Loggers = log.getLoggers() as Loggers
|
||||
let logLevelsConfig: Record<string, log.LogLevelDesc> = {}
|
||||
const logCache = new Set()
|
||||
let logFile: fs.WriteStream | null
|
||||
|
||||
const originalFactory = log.methodFactory
|
||||
const wdioLoggerMethodFactory = function (this: log.Logger, methodName: log.LogLevelNames, logLevel: log.LogLevelNumbers, loggerName: string) {
|
||||
const rawMethod = originalFactory(methodName, logLevel, loggerName)
|
||||
return (...args: string[]) => {
|
||||
/**
|
||||
* create logFile lazily
|
||||
*/
|
||||
if (!logFile && process.env.WDIO_LOG_PATH) {
|
||||
logFile = fs.createWriteStream(process.env.WDIO_LOG_PATH)
|
||||
}
|
||||
|
||||
/**
|
||||
* split `prefixer: value` sting to `prefixer: ` and `value`
|
||||
* so that SERIALIZERS can match certain string
|
||||
*/
|
||||
const match = Object.values(matches).filter(x => args[0].endsWith(`: ${x}`))[0]
|
||||
if (match) {
|
||||
const prefixStr = args.shift()!.slice(0, -match.length - 1)
|
||||
args.unshift(prefixStr, match)
|
||||
}
|
||||
|
||||
args = args.map((arg) => {
|
||||
for (const s of SERIALIZERS) {
|
||||
if (s.matches(arg)) {
|
||||
return s.serialize(arg)
|
||||
}
|
||||
}
|
||||
return arg
|
||||
})
|
||||
|
||||
const logText = ansiStrip(`${util.format.apply(this, args as [format: string, ...params: string[]])}\n`)
|
||||
if (logFile && logFile.writable) {
|
||||
/**
|
||||
* empty logging cache if stuff got logged before
|
||||
*/
|
||||
if (logCache.size) {
|
||||
logCache.forEach((log) => {
|
||||
if (logFile) {
|
||||
logFile.write(log)
|
||||
}
|
||||
})
|
||||
logCache.clear()
|
||||
}
|
||||
|
||||
if (!logsContainInitPackageError(logText)) {
|
||||
return logFile.write(logText)
|
||||
}
|
||||
// If we get Error during init of integration packages, write logs to both "outputDir" and the terminal
|
||||
logFile.write(logText)
|
||||
}
|
||||
|
||||
logCache.add(logText)
|
||||
rawMethod(...args)
|
||||
}
|
||||
}
|
||||
|
||||
const progress = function (this: any, data: string) {
|
||||
if (process.stdout.isTTY && this.getLevel() <= log.levels.INFO) {
|
||||
const level = 'progress'
|
||||
const timestampFormatter = chalk.gray(new Date().toISOString())
|
||||
const levelFormatter = chalk[COLORS[level]](level.toUpperCase())
|
||||
const nameFormatter = chalk.whiteBright(this.name)
|
||||
const _data = data.length > 0 ? `${timestampFormatter} ${levelFormatter} ${nameFormatter}: ${data}` : '\r\x1b[K\x1b[?25h'
|
||||
process.stdout.write('\u001B[?25l') // Disable cursor in terminal
|
||||
process.stdout.write(`${_data}\r`)
|
||||
}
|
||||
}
|
||||
|
||||
export default function getLogger (name: string) {
|
||||
/**
|
||||
* check if logger was already initiated
|
||||
*/
|
||||
if (loggers[name]) {
|
||||
return loggers[name]
|
||||
}
|
||||
|
||||
let logLevel: log.LogLevelDesc = (process.env.WDIO_LOG_LEVEL || DEFAULT_LEVEL) as log.LogLevelDesc
|
||||
const logLevelName = getLogLevelName(name)
|
||||
if (logLevelsConfig[logLevelName]) {
|
||||
logLevel = logLevelsConfig[logLevelName]
|
||||
}
|
||||
|
||||
loggers[name] = log.getLogger(name) as LoggerInterface
|
||||
loggers[name].setLevel(logLevel)
|
||||
loggers[name].methodFactory = wdioLoggerMethodFactory
|
||||
loggers[name].progress = progress
|
||||
prefix.apply(loggers[name], {
|
||||
template: '%t %l %n:',
|
||||
timestampFormatter: (date) => chalk.gray(date.toISOString()),
|
||||
levelFormatter: (level: string) => chalk[COLORS[level]](level.toUpperCase()),
|
||||
nameFormatter: (name) => chalk.whiteBright(name)
|
||||
})
|
||||
return loggers[name]
|
||||
}
|
||||
/**
|
||||
* Wait for writable stream to be flushed.
|
||||
* Calling this prevents part of the logs in the very env to be lost.
|
||||
*/
|
||||
getLogger.waitForBuffer = async () => new Promise<void>(resolve => {
|
||||
// @ts-ignore
|
||||
if (logFile && Array.isArray(logFile.writableBuffer) && logFile.writableBuffer.length !== 0) {
|
||||
return setTimeout(async () => {
|
||||
await getLogger.waitForBuffer()
|
||||
resolve()
|
||||
}, 20)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
getLogger.setLevel = (name: string, level: log.LogLevelDesc) => loggers[name].setLevel(level)
|
||||
getLogger.clearLogger = () => {
|
||||
if (logFile) {
|
||||
logFile.end()
|
||||
}
|
||||
logFile = null
|
||||
}
|
||||
getLogger.setLogLevelsConfig = (logLevels: Record<string, log.LogLevelDesc> = {}, wdioLogLevel: log.LogLevelDesc = DEFAULT_LEVEL) => {
|
||||
/**
|
||||
* set log level
|
||||
*/
|
||||
if (process.env.WDIO_LOG_LEVEL === undefined) {
|
||||
process.env.WDIO_LOG_LEVEL = wdioLogLevel as string
|
||||
}
|
||||
|
||||
logLevelsConfig = {}
|
||||
|
||||
/**
|
||||
* build logLevelsConfig object
|
||||
*/
|
||||
Object.entries(logLevels).forEach(([logName, logLevel]) => {
|
||||
const logLevelName = getLogLevelName(logName)
|
||||
logLevelsConfig[logLevelName] = logLevel
|
||||
})
|
||||
|
||||
/**
|
||||
* set log level for each logger
|
||||
*/
|
||||
Object.keys(loggers).forEach(logName => {
|
||||
const logLevelName = getLogLevelName(logName)
|
||||
|
||||
/**
|
||||
* either apply log level from logLevels object or use global logLevel
|
||||
*/
|
||||
const logLevel = typeof logLevelsConfig[logLevelName] !== 'undefined' ? logLevelsConfig[logLevelName] : process.env.WDIO_LOG_LEVEL as log.LogLevelDesc
|
||||
|
||||
loggers[logName].setLevel(logLevel)
|
||||
})
|
||||
}
|
||||
const getLogLevelName = (logName: string) => logName.split(':').shift() as log.LogLevelDesc
|
||||
|
||||
export type Logger = LoggerInterface
|
||||
|
||||
function logsContainInitPackageError(logText: string) {
|
||||
return ERROR_LOG_VALIDATOR.every(pattern => logText.includes(pattern))
|
||||
}
|
||||
|
||||
const ERROR_LOG_VALIDATOR = [
|
||||
'Couldn\'t find plugin',
|
||||
'neither as wdio scoped package',
|
||||
'nor as community package',
|
||||
'Please make sure you have it installed'
|
||||
]
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import fs from 'node:fs'
|
||||
import { it, describe, expect, vi, afterEach, beforeEach, afterAll } from 'vitest'
|
||||
|
||||
import nodeLogger from '../src/node.js'
|
||||
import nodeLogger2 from '../build/node.js'
|
||||
import nodeLogger from '../src/index.js'
|
||||
import nodeLogger2 from '../build/index.js'
|
||||
|
||||
import type log from 'loglevel'
|
||||
|
||||
|
|
@ -151,7 +151,6 @@ describe('wdio-logger node', () => {
|
|||
// @ts-ignore
|
||||
return writableBuffer
|
||||
},
|
||||
// @ts-expect-error
|
||||
end: vi.fn()
|
||||
}))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -28,8 +28,8 @@
|
|||
"types": "./build/index.d.ts"
|
||||
},
|
||||
"./common": {
|
||||
"import": "./build/common.js",
|
||||
"types": "./build/common.d.ts"
|
||||
"source": "./src/common.ts",
|
||||
"import": "./build/common.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ type EventTypes = 'hook' | 'test' | 'suite'
|
|||
type EventTypeProps = '_hookCnt' | '_testCnt' | '_suiteCnt'
|
||||
interface ParsedConfiguration extends Required<Options.Testrunner> {
|
||||
rootDir: string
|
||||
mochaOpts: MochaOptsImport
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -8,8 +8,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"repository": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "build",
|
||||
"rootDir": "src",
|
||||
"removeComments": false
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
|
|
@ -25,8 +25,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"import": "./build/index.js",
|
||||
"types": "./build/index.d.ts"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"name": "@wdio/reporter-cjs",
|
||||
"type": "commonjs",
|
||||
"private": true
|
||||
}
|
||||
|
|
@ -25,19 +25,15 @@
|
|||
"access": "public"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "./cjs/index.js",
|
||||
"main": "./build/index.cjs",
|
||||
"module": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": [
|
||||
{
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"require": "./cjs/index.js"
|
||||
},
|
||||
"./cjs/index.js"
|
||||
]
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"require": "./build/index.cjs"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import type { Suite } from './stats/suite.js'
|
|||
import SuiteStats from './stats/suite.js'
|
||||
import type { Hook } from './stats/hook.js'
|
||||
import HookStats from './stats/hook.js'
|
||||
import TestStats, { Test } from './stats/test.js'
|
||||
import TestStats, { type Test } from './stats/test.js'
|
||||
import RunnerStats from './stats/runner.js'
|
||||
import type { AfterCommandArgs, BeforeCommandArgs, CommandArgs, Tag, Argument } from './types.js'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"extends": "./tsconfig.prod.json",
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "Node",
|
||||
"outDir": "./cjs",
|
||||
"declaration": false,
|
||||
"declarationMap": false
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -24,8 +24,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ export default class BrowserFramework implements Omit<TestFramework, 'init'> {
|
|||
* is no need to call the url command again
|
||||
*/
|
||||
if (!this._config.sessionId) {
|
||||
await browser.url(`/?cid=${this._cid}&spec=${url.parse(spec).pathname}`)
|
||||
await browser.url(`/?cid=${this._cid}&spec=${(new URL(spec)).pathname}`)
|
||||
}
|
||||
// await browser.debug()
|
||||
|
||||
|
|
@ -473,8 +473,8 @@ export default class BrowserFramework implements Omit<TestFramework, 'init'> {
|
|||
const logs = typeof browser.getLogs === 'function'
|
||||
? (await browser.getLogs('browser').catch(() => []))
|
||||
: []
|
||||
const severeLogs = logs.filter((log: LogMessage) => log.level === 'SEVERE') as LogMessage[]
|
||||
if (logs.length) {
|
||||
const severeLogs = logs.filter((log: LogMessage) => log.level === 'SEVERE' && log.source !== 'deprecation') as LogMessage[]
|
||||
if (severeLogs.length) {
|
||||
if (!this.#retryOutdatedOptimizeDep && severeLogs.some((log) => log.message?.includes('(Outdated Optimize Dep)'))) {
|
||||
log.info('Retry test run due to outdated optimize dep')
|
||||
this.#retryOutdatedOptimizeDep = true
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"types": ["@wdio/globals/types"]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
|
|
@ -25,8 +25,10 @@
|
|||
"type": "module",
|
||||
"types": "./build/index.d.ts",
|
||||
"exports": {
|
||||
".": "./build/index.js",
|
||||
"./package.json": "./package.json"
|
||||
".": {
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js"
|
||||
}
|
||||
},
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.prod",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"types": ["@wdio/globals/types"]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../@types"
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue