rewrite @wdio/cli into ESM
This commit is contained in:
parent
389b5131a1
commit
3c541d3892
43 changed files with 794 additions and 742 deletions
|
|
@ -24,7 +24,10 @@ class DotReporter {
|
|||
}
|
||||
}
|
||||
|
||||
class RunnerMock {}
|
||||
class RunnerMock {
|
||||
shutdown = vi.fn()
|
||||
initialise = vi.fn()
|
||||
}
|
||||
class FoobarServiceMock {
|
||||
beforeSuite () {}
|
||||
afterCommand () {}
|
||||
|
|
@ -66,7 +69,7 @@ const pluginMocks = {
|
|||
}
|
||||
|
||||
export const initialisePlugin = vi.fn().mockImplementation(
|
||||
(name: keyof typeof frameworkMocks, type: keyof typeof pluginMocks) => (
|
||||
async (name: keyof typeof frameworkMocks, type: keyof typeof pluginMocks) => (
|
||||
{ default: (pluginMocks[type] as any)[name] }
|
||||
)
|
||||
)
|
||||
|
|
|
|||
2
__mocks__/async-exit-hook.ts
Normal file
2
__mocks__/async-exit-hook.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import { vi } from 'vitest'
|
||||
export default vi.fn()
|
||||
6
__mocks__/chokidar.ts
Normal file
6
__mocks__/chokidar.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { vi } from 'vitest'
|
||||
const chokidar: any = {}
|
||||
chokidar.watch = vi.fn().mockReturnValue(chokidar)
|
||||
chokidar.on =vi.fn().mockReturnValue(chokidar)
|
||||
|
||||
export default chokidar
|
||||
4
__mocks__/ejs.ts
Normal file
4
__mocks__/ejs.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { vi } from 'vitest'
|
||||
export default {
|
||||
renderFile: vi.fn().mockImplementation((...args: any[]) => args.pop()())
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { vi } from 'vitest'
|
||||
export default {
|
||||
prompt: jest.fn().mockReturnValue(Promise.resolve({
|
||||
prompt: vi.fn().mockReturnValue(Promise.resolve({
|
||||
runner: '@wdio/local-runner--$local',
|
||||
framework: '@wdio/mocha-framework$--$mocha',
|
||||
reporters: ['@wdio/spec-reporter$--$spec'],
|
||||
5
__mocks__/log-update.ts
Normal file
5
__mocks__/log-update.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { vi } from 'vitest'
|
||||
const logUpdateMock: any = vi.fn()
|
||||
logUpdateMock.clear = vi.fn()
|
||||
|
||||
export default logUpdateMock
|
||||
2
__mocks__/recursive-readdir.ts
Normal file
2
__mocks__/recursive-readdir.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import { vi } from 'vitest'
|
||||
export default vi.fn()
|
||||
14
__mocks__/yargs/yargs.ts
Normal file
14
__mocks__/yargs/yargs.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { vi } from 'vitest'
|
||||
const yargs: any = {}
|
||||
yargs.commandDir = vi.fn(() => yargs)
|
||||
yargs.example = vi.fn(() => yargs)
|
||||
yargs.argv = { _: ['wdio.conf.js'] }
|
||||
yargs.epilogue = vi.fn().mockReturnValue(yargs)
|
||||
yargs.options = vi.fn(() => yargs)
|
||||
yargs.updateStrings = vi.fn(() => yargs)
|
||||
yargs.parse = vi.fn().mockReturnValue(yargs.argv)
|
||||
yargs.env = vi.fn().mockReturnValue(yargs)
|
||||
yargs.help = vi.fn().mockReturnValue(yargs)
|
||||
|
||||
export default vi.fn().mockReturnValue(yargs)
|
||||
export { yargs }
|
||||
2
__mocks__/yarn-install.ts
Normal file
2
__mocks__/yarn-install.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import { vi } from 'vitest'
|
||||
export default vi.fn().mockReturnValue({ status: 0 })
|
||||
|
|
@ -5,12 +5,11 @@
|
|||
"author": "Christian Bromann <mail@bromann.dev>",
|
||||
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-cli",
|
||||
"license": "MIT",
|
||||
"main": "./build/index",
|
||||
"bin": {
|
||||
"wdio": "./bin/wdio.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.13 || >=18"
|
||||
"node": "^16.13 || >=18"
|
||||
},
|
||||
"scripts": {
|
||||
"copy": "copyfiles -u 1 -V \"src/templates/**/*\" ./build/"
|
||||
|
|
@ -28,6 +27,20 @@
|
|||
"bugs": {
|
||||
"url": "https://github.com/webdriverio/webdriverio/issues"
|
||||
},
|
||||
"main": "./build/index.cjs.js",
|
||||
"type": "module",
|
||||
"module": "./build/index.js",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"import": "./build/index.js",
|
||||
"require": "./build/index.cjs.js"
|
||||
},
|
||||
"./build/index.cjs.js"
|
||||
]
|
||||
},
|
||||
"types": "./build/index.d.ts",
|
||||
"typeScriptVersion": "3.8.3",
|
||||
"dependencies": {
|
||||
"@types/ejs": "^3.0.5",
|
||||
"@types/fs-extra": "^9.0.4",
|
||||
|
|
@ -61,5 +74,7 @@
|
|||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"types": "./build/index.d.ts"
|
||||
"devDependencies": {
|
||||
"@types/yargs": "^17.0.10"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,22 +3,21 @@ import util from 'node:util'
|
|||
import fs from 'fs-extra'
|
||||
import inquirer from 'inquirer'
|
||||
import yarnInstall from 'yarn-install'
|
||||
import type yargs from 'yargs'
|
||||
|
||||
import {
|
||||
CONFIG_HELPER_INTRO, CLI_EPILOGUE, COMPILER_OPTIONS,
|
||||
TS_COMPILER_INSTRUCTIONS, SUPPORTED_PACKAGES,
|
||||
CONFIG_HELPER_SUCCESS_MESSAGE,
|
||||
DEPENDENCIES_INSTALLATION_MESSAGE
|
||||
} from '../constants'
|
||||
DEPENDENCIES_INSTALLATION_MESSAGE,
|
||||
pkg
|
||||
} from '../constants.js'
|
||||
import {
|
||||
addServiceDeps, convertPackageHashToObject, renderConfigurationFile,
|
||||
hasFile, generateTestFiles, getAnswers, getPathForFileGeneration,
|
||||
hasPackage
|
||||
} from '../utils'
|
||||
import { ConfigCommandArguments, ParsedAnswers } from '../types'
|
||||
import yargs from 'yargs'
|
||||
|
||||
const pkg = require('../../package.json')
|
||||
} from '../utils.js'
|
||||
import type { ConfigCommandArguments, ParsedAnswers } from '../types'
|
||||
|
||||
export const command = 'config'
|
||||
export const desc = 'Initialize WebdriverIO and setup configuration in your current project.'
|
||||
|
|
@ -45,6 +44,8 @@ export const builder = (yargs: yargs.Argv) => {
|
|||
}
|
||||
|
||||
const runConfig = async function (useYarn: boolean, yes: boolean, exit = false) {
|
||||
console.info('1')
|
||||
|
||||
console.log(CONFIG_HELPER_INTRO)
|
||||
const answers = await getAnswers(yes)
|
||||
const frameworkPackage = convertPackageHashToObject(answers.framework)
|
||||
|
|
@ -66,6 +67,7 @@ const runConfig = async function (useYarn: boolean, yes: boolean, exit = false)
|
|||
*/
|
||||
|
||||
const parsedPaths = getPathForFileGeneration(answers)
|
||||
console.info('2')
|
||||
|
||||
const parsedAnswers: ParsedAnswers = {
|
||||
...answers,
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@
|
|||
import path from 'node:path'
|
||||
import fs from 'fs-extra'
|
||||
import yarnInstall from 'yarn-install'
|
||||
import type yargs from 'yargs'
|
||||
|
||||
import {
|
||||
replaceConfig,
|
||||
findInConfig,
|
||||
addServiceDeps,
|
||||
convertPackageHashToObject
|
||||
} from '../utils'
|
||||
import { missingConfigurationPrompt } from './config'
|
||||
import { InstallCommandArguments, SupportedPackage } from '../types'
|
||||
import { SUPPORTED_PACKAGES, CLI_EPILOGUE } from '../constants'
|
||||
import yargs from 'yargs'
|
||||
} from '../utils.js'
|
||||
import { missingConfigurationPrompt } from './config.js'
|
||||
import { SUPPORTED_PACKAGES, CLI_EPILOGUE } from '../constants.js'
|
||||
import type { InstallCommandArguments, SupportedPackage } from '../types'
|
||||
|
||||
const supportedInstallations = {
|
||||
plugin: SUPPORTED_PACKAGES.plugin.map(({ value }) => convertPackageHashToObject(value)),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import yargs from 'yargs'
|
||||
import pickBy from 'lodash.pickby'
|
||||
import { remote } from 'webdriverio'
|
||||
import { cmdArgs as runCmdArgs } from './run'
|
||||
import { getCapabilities } from '../utils'
|
||||
import { ReplCommandArguments } from '../types'
|
||||
import { CLI_EPILOGUE } from '../constants'
|
||||
import yargs from 'yargs'
|
||||
|
||||
import { cmdArgs as runCmdArgs } from './run.js'
|
||||
import { getCapabilities } from '../utils.js'
|
||||
import { CLI_EPILOGUE } from '../constants.js'
|
||||
import type { ReplCommandArguments } from '../types'
|
||||
|
||||
const IGNORED_ARGS = [
|
||||
'bail', 'framework', 'reporters', 'suite', 'spec', 'exclude',
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
import path from 'node:path'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
import { missingConfigurationPrompt } from './config'
|
||||
import { RunCommandArguments } from '../types'
|
||||
|
||||
import Launcher from '../launcher'
|
||||
import Watcher from '../watcher'
|
||||
import { CLI_EPILOGUE } from '../constants'
|
||||
import yargs from 'yargs'
|
||||
|
||||
import Launcher from '../launcher.js'
|
||||
import Watcher from '../watcher.js'
|
||||
import { missingConfigurationPrompt } from './config.js'
|
||||
import { CLI_EPILOGUE } from '../constants.js'
|
||||
import type { RunCommandArguments } from '../types'
|
||||
|
||||
export const command = 'run <configPath>'
|
||||
|
||||
export const desc = 'Run your WDIO configuration file to initialize your tests. (default)'
|
||||
|
|
@ -129,14 +128,14 @@ export function launch (wdioConfPath: string, params: Partial<RunCommandArgument
|
|||
return launcher.run()
|
||||
.then((...args) => {
|
||||
/* istanbul ignore if */
|
||||
if (!process.env.JEST_WORKER_ID) {
|
||||
if (!process.env.VITEST_WORKER_ID) {
|
||||
process.exit(...args)
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
/* istanbul ignore if */
|
||||
if (!process.env.JEST_WORKER_ID) {
|
||||
if (!process.env.VITEST_WORKER_ID) {
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import { validateServiceAnswers, hasFile, getDefaultFiles } from './utils'
|
||||
import { Questionnair } from './types'
|
||||
import { createRequire } from 'node:module'
|
||||
|
||||
const pkg = require('../package.json')
|
||||
import { validateServiceAnswers, hasFile, getDefaultFiles } from './utils.js'
|
||||
import type { Questionnair } from './types'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
export const pkg = require('../package.json')
|
||||
|
||||
export const CLI_EPILOGUE = `Documentation: https://webdriver.io\n@wdio/cli (v${pkg.version})`
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import path from 'node:path'
|
|||
import yargs from 'yargs/yargs'
|
||||
import { hideBin } from 'yargs/helpers'
|
||||
|
||||
import Launcher from './launcher'
|
||||
import { handler, cmdArgs } from './commands/run'
|
||||
import { CLI_EPILOGUE } from './constants'
|
||||
import { RunCommandArguments } from './types'
|
||||
import Launcher from './launcher.js'
|
||||
import { handler, cmdArgs } from './commands/run.js'
|
||||
import { CLI_EPILOGUE } from './constants.js'
|
||||
import type { RunCommandArguments } from './types'
|
||||
|
||||
const DEFAULT_CONFIG_FILENAME = 'wdio.conf.js'
|
||||
const DESCRIPTION = [
|
||||
|
|
@ -82,4 +82,4 @@ export const run = async () => {
|
|||
}
|
||||
|
||||
export default Launcher
|
||||
export * from './types'
|
||||
export * from './types.js'
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import chalk from 'chalk'
|
||||
import { EventEmitter } from 'node:events'
|
||||
import chalk from 'chalk'
|
||||
import logger from '@wdio/logger'
|
||||
import type { Options, Capabilities, Workers } from '@wdio/types'
|
||||
|
||||
import { getRunnerName, HookError } from './utils'
|
||||
import { getRunnerName, HookError } from './utils.js'
|
||||
|
||||
const log = logger('@wdio/cli')
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import { ConfigParser } from '@wdio/config'
|
|||
import { initialisePlugin, initialiseLauncherService, sleep } from '@wdio/utils'
|
||||
import type { Options, Capabilities, Services } from '@wdio/types'
|
||||
|
||||
import CLInterface from './interface'
|
||||
import { RunCommandArguments } from './types'
|
||||
import { runLauncherHook, runOnCompleteHook, runServiceHook, HookError } from './utils'
|
||||
import CLInterface from './interface.js'
|
||||
import { runLauncherHook, runOnCompleteHook, runServiceHook, HookError } from './utils.js'
|
||||
import type { RunCommandArguments } from './types'
|
||||
|
||||
const log = logger('@wdio/cli:launcher')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Options, Reporters } from '@wdio/types'
|
||||
import { BACKEND_CHOICES, REGION_OPTION, COMPILER_OPTION_ANSWERS } from './constants'
|
||||
import type { Options, Reporters } from '@wdio/types'
|
||||
import type { BACKEND_CHOICES, REGION_OPTION, COMPILER_OPTION_ANSWERS } from './constants'
|
||||
|
||||
type ValueOf<T> = T[keyof T]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
import { dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { createRequire } from 'node:module'
|
||||
import { execSync } from 'node:child_process'
|
||||
import { promisify } from 'node:util'
|
||||
|
||||
import fs from 'fs-extra'
|
||||
import ejs from 'ejs'
|
||||
import path from 'node:path'
|
||||
|
|
@ -6,16 +12,16 @@ import pickBy from 'lodash.pickby'
|
|||
import logger from '@wdio/logger'
|
||||
import readDir from 'recursive-readdir'
|
||||
import { SevereServiceError } from 'webdriverio'
|
||||
import { execSync } from 'node:child_process'
|
||||
import { promisify } from 'node:util'
|
||||
import { ConfigParser } from '@wdio/config'
|
||||
import { CAPABILITY_KEYS } from '@wdio/protocols'
|
||||
import type { Options, Capabilities, Services } from '@wdio/types'
|
||||
|
||||
import { ReplCommandArguments, Questionnair, SupportedPackage, OnCompleteResult, ParsedAnswers } from './types'
|
||||
import { EXCLUSIVE_SERVICES, ANDROID_CONFIG, IOS_CONFIG, QUESTIONNAIRE } from './constants'
|
||||
import { EXCLUSIVE_SERVICES, ANDROID_CONFIG, IOS_CONFIG, QUESTIONNAIRE } from './constants.js'
|
||||
import type { ReplCommandArguments, Questionnair, SupportedPackage, OnCompleteResult, ParsedAnswers } from './types'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const log = logger('@wdio/cli:utils')
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const TEMPLATE_ROOT_DIR = path.join(__dirname, 'templates', 'exampleFiles')
|
||||
const renderFile = promisify(ejs.renderFile) as (path: string, data: Record<string, any>) => Promise<string>
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ import logger from '@wdio/logger'
|
|||
import pickBy from 'lodash.pickby'
|
||||
import flattenDeep from 'lodash.flattendeep'
|
||||
import union from 'lodash.union'
|
||||
|
||||
import Launcher from './launcher'
|
||||
import type { Capabilities, Workers } from '@wdio/types'
|
||||
import { RunCommandArguments, ValueKeyIteratee } from './types.js'
|
||||
|
||||
import Launcher from './launcher.js'
|
||||
import type { RunCommandArguments, ValueKeyIteratee } from './types'
|
||||
|
||||
const log = logger('@wdio/cli:watch')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
export default jest.fn()
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
const chokidar = {}
|
||||
chokidar.watch = jest.fn().mockReturnValue(chokidar)
|
||||
chokidar.on =jest.fn().mockReturnValue(chokidar)
|
||||
|
||||
export default chokidar
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
export default {
|
||||
renderFile: jest.fn().mockImplementation((...args) => args.pop()())
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
const logUpdateMock = jest.fn()
|
||||
logUpdateMock.clear = jest.fn()
|
||||
|
||||
export default logUpdateMock
|
||||
|
|
@ -1 +0,0 @@
|
|||
export default jest.fn()
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
const yargs: any = {}
|
||||
yargs.commandDir = jest.fn(() => yargs)
|
||||
yargs.example = jest.fn(() => yargs)
|
||||
yargs.argv = { _: ['wdio.conf.js'] }
|
||||
yargs.epilogue = jest.fn().mockReturnValue(yargs)
|
||||
yargs.options = jest.fn(() => yargs)
|
||||
yargs.updateStrings = jest.fn(() => yargs)
|
||||
yargs.parse = jest.fn().mockReturnValue(yargs.argv)
|
||||
yargs.env = jest.fn().mockReturnValue(yargs)
|
||||
yargs.help = jest.fn().mockReturnValue(yargs)
|
||||
|
||||
export default jest.fn().mockReturnValue(yargs)
|
||||
export { yargs }
|
||||
|
|
@ -1 +0,0 @@
|
|||
export default jest.fn().mockReturnValue({ status: 0 })
|
||||
|
|
@ -1,22 +1,8 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`getCapabilities should get capability from wdio.conf.js 1`] = `
|
||||
Object {
|
||||
"capabilities": Object {
|
||||
"acceptInsecureCerts": true,
|
||||
"browserName": "chrome",
|
||||
"goog:chromeOptions": Object {
|
||||
"args": Array [
|
||||
"window-size=8000,1200",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`getCapabilities should return driver with capabilities for android 1`] = `
|
||||
Object {
|
||||
"capabilities": Object {
|
||||
exports[`getCapabilities > should return driver with capabilities for android 1`] = `
|
||||
{
|
||||
"capabilities": {
|
||||
"app": "foo.apk",
|
||||
"automationName": "UiAutomator2",
|
||||
"deviceName": "Test",
|
||||
|
|
@ -27,9 +13,9 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`getCapabilities should return driver with capabilities for android 2`] = `
|
||||
Object {
|
||||
"capabilities": Object {
|
||||
exports[`getCapabilities > should return driver with capabilities for android 2`] = `
|
||||
{
|
||||
"capabilities": {
|
||||
"automationName": "UiAutomator2",
|
||||
"browserName": "Chrome",
|
||||
"deviceName": "Test",
|
||||
|
|
@ -40,17 +26,17 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`getCapabilities should return driver with capabilities for desktop 1`] = `
|
||||
Object {
|
||||
"capabilities": Object {
|
||||
exports[`getCapabilities > should return driver with capabilities for desktop 1`] = `
|
||||
{
|
||||
"capabilities": {
|
||||
"browserName": "chrome",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`getCapabilities should return driver with capabilities for ios 1`] = `
|
||||
Object {
|
||||
"capabilities": Object {
|
||||
exports[`getCapabilities > should return driver with capabilities for ios 1`] = `
|
||||
{
|
||||
"capabilities": {
|
||||
"app": "foo.app",
|
||||
"automationName": "XCUITest",
|
||||
"deviceName": "fooName",
|
||||
|
|
@ -61,9 +47,9 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`getCapabilities should return driver with capabilities for ios 2`] = `
|
||||
Object {
|
||||
"capabilities": Object {
|
||||
exports[`getCapabilities > should return driver with capabilities for ios 2`] = `
|
||||
{
|
||||
"capabilities": {
|
||||
"automationName": "XCUITest",
|
||||
"browserName": "Safari",
|
||||
"deviceName": "iPhone Simulator",
|
||||
|
|
@ -74,10 +60,10 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`getCapabilities should through capability not found 1`] = `"No capability found in given config file with the provided capability indexed/named property: 5. Please check the capability in your wdio config file."`;
|
||||
exports[`getCapabilities > should through capability not found 1`] = `"No capability found in given config file with the provided capability indexed/named property: 5. Please check the capability in your wdio config file."`;
|
||||
|
||||
exports[`getCapabilities should throw capability not provided 1`] = `"Please provide index/named property of capability to use from the capabilities array/object in wdio config file"`;
|
||||
exports[`getCapabilities > should throw capability not provided 1`] = `"Please provide index/named property of capability to use from the capabilities array/object in wdio config file"`;
|
||||
|
||||
exports[`getCapabilities should throw config not found error 1`] = `"Config File not found: ./test.js"`;
|
||||
exports[`getCapabilities > should throw config not found error 1`] = `"Config File not found: ./test.js"`;
|
||||
|
||||
exports[`getCapabilities should throw config not found error 2`] = `"Could not parse ./test.js, failed with error : ups"`;
|
||||
exports[`getCapabilities > should throw config not found error 2`] = `"Could not parse ./test.js, failed with error : ups"`;
|
||||
|
|
|
|||
|
|
@ -1,150 +1,15 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`install compliant NPM tag packages it should install tagged version if cli is tagged with beta 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
exports[`install compliant NPM tag packages > it should install tagged version if cli is tagged with beta 1`] = `
|
||||
[
|
||||
[
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
"@wdio/local-runner@beta
|
||||
- @wdio/mocha-framework@beta
|
||||
- @wdio/crossbrowsertesting-service@beta
|
||||
- wdio-lambdatest-service
|
||||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
Array [
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
\\"types\\": [\\"node\\", \\"webdriverio/async\\", \\"@wdio/mocha-framework\\", \\"expect-webdriverio\\", \\"@wdio/crossbrowsertesting-service\\"]
|
||||
}
|
||||
}
|
||||
|
||||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
$ npx wdio run test/wdio.conf.ts
|
||||
",
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`install compliant NPM tag packages it should install tagged version if cli is tagged with latest 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
"@wdio/local-runner@latest
|
||||
- @wdio/mocha-framework@latest
|
||||
- @wdio/crossbrowsertesting-service@latest
|
||||
- wdio-lambdatest-service
|
||||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
Array [
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
\\"types\\": [\\"node\\", \\"webdriverio/async\\", \\"@wdio/mocha-framework\\", \\"expect-webdriverio\\", \\"@wdio/crossbrowsertesting-service\\"]
|
||||
}
|
||||
}
|
||||
|
||||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
$ npx wdio run test/wdio.conf.ts
|
||||
",
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`install compliant NPM tag packages it should install tagged version if cli is tagged with next 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
"@wdio/local-runner@next
|
||||
- @wdio/mocha-framework@next
|
||||
- @wdio/crossbrowsertesting-service@next
|
||||
- wdio-lambdatest-service
|
||||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
Array [
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
\\"types\\": [\\"node\\", \\"webdriverio/async\\", \\"@wdio/mocha-framework\\", \\"expect-webdriverio\\", \\"@wdio/crossbrowsertesting-service\\"]
|
||||
}
|
||||
}
|
||||
|
||||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
$ npx wdio run test/wdio.conf.ts
|
||||
",
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`install compliant NPM tag packages it should not install tagged version if cli is tagged with a specific version 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
|
|
@ -155,11 +20,11 @@ Installing wdio packages:
|
|||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
|
|
@ -170,7 +35,142 @@ Packages installed successfully, creating configuration file...",
|
|||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
$ npx wdio run test/wdio.conf.ts
|
||||
",
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`install compliant NPM tag packages > it should install tagged version if cli is tagged with latest 1`] = `
|
||||
[
|
||||
[
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
[
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
"@wdio/local-runner
|
||||
- @wdio/mocha-framework
|
||||
- @wdio/crossbrowsertesting-service
|
||||
- wdio-lambdatest-service
|
||||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
[
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
[
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
\\"types\\": [\\"node\\", \\"webdriverio/async\\", \\"@wdio/mocha-framework\\", \\"expect-webdriverio\\", \\"@wdio/crossbrowsertesting-service\\"]
|
||||
}
|
||||
}
|
||||
|
||||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
[
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
$ npx wdio run test/wdio.conf.ts
|
||||
",
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`install compliant NPM tag packages > it should install tagged version if cli is tagged with next 1`] = `
|
||||
[
|
||||
[
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
[
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
"@wdio/local-runner
|
||||
- @wdio/mocha-framework
|
||||
- @wdio/crossbrowsertesting-service
|
||||
- wdio-lambdatest-service
|
||||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
[
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
[
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
\\"types\\": [\\"node\\", \\"webdriverio/async\\", \\"@wdio/mocha-framework\\", \\"expect-webdriverio\\", \\"@wdio/crossbrowsertesting-service\\"]
|
||||
}
|
||||
}
|
||||
|
||||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
[
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
$ npx wdio run test/wdio.conf.ts
|
||||
",
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`install compliant NPM tag packages > it should not install tagged version if cli is tagged with a specific version 1`] = `
|
||||
[
|
||||
[
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
[
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
"@wdio/local-runner
|
||||
- @wdio/mocha-framework
|
||||
- @wdio/crossbrowsertesting-service
|
||||
- wdio-lambdatest-service
|
||||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
[
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
[
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
\\"types\\": [\\"node\\", \\"webdriverio/async\\", \\"@wdio/mocha-framework\\", \\"expect-webdriverio\\", \\"@wdio/crossbrowsertesting-service\\"]
|
||||
}
|
||||
}
|
||||
|
||||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
[
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
|
|
@ -181,15 +181,15 @@ $ npx wdio run test/wdio.conf.ts
|
|||
`;
|
||||
|
||||
exports[`prints TypeScript setup message 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
[
|
||||
[
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
|
|
@ -200,11 +200,11 @@ Installing wdio packages:
|
|||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
|
|
@ -215,7 +215,7 @@ Packages installed successfully, creating configuration file...",
|
|||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
|
|
@ -226,15 +226,15 @@ $ npx wdio run test/wdio.conf.ts
|
|||
`;
|
||||
|
||||
exports[`prints TypeScript setup message with ts-node installed 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
[
|
||||
[
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
|
|
@ -245,11 +245,11 @@ Installing wdio packages:
|
|||
- ts-node
|
||||
- typescript",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"To have TypeScript support please add the following packages to your \\"types\\" list:
|
||||
{
|
||||
\\"compilerOptions\\": {
|
||||
|
|
@ -260,7 +260,7 @@ Packages installed successfully, creating configuration file...",
|
|||
For for information on TypeScript integration check out: https://webdriver.io/docs/typescript
|
||||
",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
|
|
@ -271,15 +271,15 @@ $ npx wdio run test/wdio.conf.ts
|
|||
`;
|
||||
|
||||
exports[`should create config file 1`] = `
|
||||
Object {
|
||||
"installedPackages": Array [
|
||||
{
|
||||
"installedPackages": [
|
||||
"@wdio/local-runner",
|
||||
"@wdio/mocha-framework",
|
||||
"@wdio/spec-reporter",
|
||||
"wdio-wait-for",
|
||||
"@wdio/sauce-service",
|
||||
],
|
||||
"parsedAnswers": Object {
|
||||
"parsedAnswers": {
|
||||
"_async": "async ",
|
||||
"_await": "await ",
|
||||
"framework": "mocha",
|
||||
|
|
@ -287,22 +287,22 @@ Object {
|
|||
"isUsingBabel": false,
|
||||
"isUsingTypeScript": false,
|
||||
"npmInstall": true,
|
||||
"packagesToInstall": Array [
|
||||
"packagesToInstall": [
|
||||
"@wdio/local-runner",
|
||||
"@wdio/mocha-framework",
|
||||
"@wdio/spec-reporter",
|
||||
"wdio-wait-for",
|
||||
"@wdio/sauce-service",
|
||||
],
|
||||
"plugins": Array [
|
||||
"plugins": [
|
||||
"wait-for",
|
||||
],
|
||||
"relativePath": "",
|
||||
"reporters": Array [
|
||||
"reporters": [
|
||||
"spec",
|
||||
],
|
||||
"runner": "local",
|
||||
"services": Array [
|
||||
"services": [
|
||||
"sauce",
|
||||
],
|
||||
"tsConfigFilePath": "test/tsconfig.json",
|
||||
|
|
@ -312,15 +312,15 @@ Object {
|
|||
`;
|
||||
|
||||
exports[`should not install @babel/register if existing 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
[
|
||||
[
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
|
|
@ -332,11 +332,11 @@ Installing wdio packages:
|
|||
- @babel/core
|
||||
- @babel/preset-env",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
|
|
@ -346,57 +346,18 @@ $ npx wdio run wdio.conf.js
|
|||
]
|
||||
`;
|
||||
|
||||
exports[`should not install npm packages when npmInstall is false 1`] = `
|
||||
[MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
To install dependencies, execute:
|
||||
npm i --save-dev @wdio/local-runner @wdio/mocha-framework @wdio/spec-reporter wdio-wait-for @wdio/sauce-service
|
||||
",
|
||||
],
|
||||
Array [
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
$ npx wdio run wdio.conf.js
|
||||
",
|
||||
],
|
||||
],
|
||||
"results": Array [
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
exports[`should not install npm packages when npmInstall is false 1`] = `[Function]`;
|
||||
|
||||
exports[`should setup Babel if not existing 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
[
|
||||
[
|
||||
"
|
||||
=========================
|
||||
WDIO Configuration Helper
|
||||
=========================
|
||||
",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Installing wdio packages:
|
||||
-",
|
||||
|
|
@ -408,11 +369,11 @@ Installing wdio packages:
|
|||
- @babel/core
|
||||
- @babel/preset-env",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Packages installed successfully, creating configuration file...",
|
||||
],
|
||||
Array [
|
||||
[
|
||||
"
|
||||
Configuration file was created successfully!
|
||||
To run your tests, execute:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { vi, describe, it, test, expect, afterEach, beforeEach } from 'vitest'
|
||||
import path from 'node:path'
|
||||
// @ts-expect-error mock
|
||||
import { yargs } from 'yargs/yargs'
|
||||
|
|
@ -7,34 +8,54 @@ import inquirer from 'inquirer'
|
|||
import pkg from '../../package.json'
|
||||
|
||||
import { handler, builder, missingConfigurationPrompt } from '../../src/commands/config'
|
||||
import { addServiceDeps, convertPackageHashToObject, renderConfigurationFile, generateTestFiles, getPathForFileGeneration } from '../../src/utils'
|
||||
import {
|
||||
getAnswers, addServiceDeps, convertPackageHashToObject, renderConfigurationFile,
|
||||
generateTestFiles, getPathForFileGeneration
|
||||
} from '../../src/utils'
|
||||
|
||||
jest.mock('../../src/utils', () => ({
|
||||
addServiceDeps: jest.fn(),
|
||||
convertPackageHashToObject: jest.fn().mockImplementation(jest.requireActual('../../src/utils').convertPackageHashToObject),
|
||||
renderConfigurationFile: jest.fn(),
|
||||
hasFile: jest.fn().mockReturnValue(false),
|
||||
hasPackage: jest.fn().mockReturnValue(false),
|
||||
getAnswers: jest.fn().mockImplementation(jest.requireActual('../../src/utils').getAnswers),
|
||||
generateTestFiles: jest.fn(),
|
||||
getPathForFileGeneration: jest.fn().mockImplementation(jest.requireActual('../../src/utils').getPathForFileGeneration),
|
||||
vi.mock('yargs/yargs')
|
||||
vi.mock('yarn-install')
|
||||
vi.mock('inquirer')
|
||||
vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger')))
|
||||
|
||||
const utils: any = await vi.importActual('../../src/utils')
|
||||
vi.mocked(convertPackageHashToObject).mockImplementation(utils.convertPackageHashToObject)
|
||||
vi.mocked(getPathForFileGeneration).mockImplementation(utils.getPathForFileGeneration)
|
||||
vi.mocked(getAnswers).mockImplementation(utils.getAnswers)
|
||||
|
||||
vi.mock('../../src/utils', async () => {
|
||||
return {
|
||||
addServiceDeps: vi.fn(),
|
||||
convertPackageHashToObject: vi.fn(),
|
||||
renderConfigurationFile: vi.fn(),
|
||||
hasFile: vi.fn().mockReturnValue(false),
|
||||
hasPackage: vi.fn().mockReturnValue(false),
|
||||
getAnswers: vi.fn(),
|
||||
generateTestFiles: vi.fn(),
|
||||
getPathForFileGeneration: vi.fn()
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('fs', () => ({
|
||||
default: {
|
||||
writeFile: vi.fn().mockResolvedValue(''),
|
||||
existsSync: vi.fn()
|
||||
}
|
||||
}))
|
||||
|
||||
jest.mock('fs')
|
||||
|
||||
jest.mock('../../package.json', () => {
|
||||
const pkg = jest.requireActual('../../package.json')
|
||||
vi.mock('../../package.json', async () => {
|
||||
const pkg = await vi.importActual('../../package.json') as any
|
||||
pkg.setFetchSpec = (fetchSpec: string) => {
|
||||
pkg._requested = { fetchSpec }
|
||||
}
|
||||
pkg.clearFetchSpec = () => {
|
||||
delete pkg._requested
|
||||
}
|
||||
return pkg
|
||||
return { default: pkg }
|
||||
})
|
||||
|
||||
const errorLogSpy = jest.spyOn(console, 'error')
|
||||
const consoleLogSpy = jest.spyOn(console, 'log')
|
||||
const errorLogSpy = vi.spyOn(console, 'error')
|
||||
const consoleLogSpy = vi.spyOn(console, 'log')
|
||||
|
||||
const args = {
|
||||
framework: '@wdio/mocha-framework$--$mocha',
|
||||
|
|
@ -52,8 +73,8 @@ const args = {
|
|||
}
|
||||
|
||||
beforeEach(() => {
|
||||
(yarnInstall as any as jest.Mock).mockClear()
|
||||
;(yarnInstall as any as jest.Mock).mockReturnValue({ status: 0 })
|
||||
vi.mocked(yarnInstall).mockClear()
|
||||
vi.mocked(yarnInstall).mockReturnValue({ status: 0 } as any)
|
||||
errorLogSpy.mockClear()
|
||||
consoleLogSpy.mockClear()
|
||||
|
||||
|
|
@ -65,16 +86,14 @@ afterEach(() => {
|
|||
})
|
||||
|
||||
test('should create config file', async () => {
|
||||
|
||||
(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve(args))
|
||||
// @ts-expect-error
|
||||
fs.promises = { writeFile: jest.fn()
|
||||
.mockReturnValue(Promise.resolve('')) }
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue(args)
|
||||
const result = await handler({} as any)
|
||||
// @ts-expect-error
|
||||
delete result.parsedAnswers.destPageObjectRootPath
|
||||
// @ts-expect-error
|
||||
delete result.parsedAnswers.destSpecRootPath
|
||||
const fileName = `${path.basename(path.dirname(result.parsedAnswers.tsConfigFilePath))}/${path.basename(result.parsedAnswers.tsConfigFilePath)}`
|
||||
result.parsedAnswers.tsConfigFilePath = fileName
|
||||
const fileName = `${path.basename(path.dirname(result.parsedAnswers!.tsConfigFilePath))}/${path.basename(result.parsedAnswers!.tsConfigFilePath)}`
|
||||
result.parsedAnswers!.tsConfigFilePath = fileName
|
||||
expect(result).toMatchSnapshot()
|
||||
expect(addServiceDeps).toBeCalledTimes(1)
|
||||
expect(convertPackageHashToObject).toBeCalledTimes(5)
|
||||
|
|
@ -97,7 +116,7 @@ test('it should properly build command', () => {
|
|||
})
|
||||
|
||||
test('should throw error if creating config file fails', async () => {
|
||||
(renderConfigurationFile as jest.Mock).mockReturnValueOnce(Promise.reject(new Error('boom!')))
|
||||
vi.mocked(renderConfigurationFile).mockReturnValueOnce(Promise.reject(new Error('boom!')))
|
||||
const err = await handler({} as any).catch((err) => err)
|
||||
expect(err.message).toContain('Error: boom!')
|
||||
})
|
||||
|
|
@ -129,10 +148,10 @@ describe('install compliant NPM tag packages', () => {
|
|||
}
|
||||
|
||||
test('it should install tagged version if cli is tagged with beta', async () => {
|
||||
setFetchSpec('beta');
|
||||
(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve(args))
|
||||
setFetchSpec('beta')
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue(args)
|
||||
// @ts-expect-error
|
||||
fs.promises = { writeFile: jest.fn()
|
||||
fs.promises = { writeFile: vi.fn()
|
||||
.mockReturnValue(Promise.resolve('')) }
|
||||
await handler({} as any)
|
||||
|
||||
|
|
@ -140,21 +159,21 @@ describe('install compliant NPM tag packages', () => {
|
|||
})
|
||||
|
||||
test('it should install tagged version if cli is tagged with next', async () => {
|
||||
setFetchSpec('next');
|
||||
(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve(args))
|
||||
// @ts-expect-error
|
||||
fs.promises = { writeFile: jest.fn()
|
||||
.mockReturnValue(Promise.resolve('')) }
|
||||
setFetchSpec('next')
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue(args)
|
||||
fs.promises = {
|
||||
writeFile: vi.fn().mockReturnValue(Promise.resolve(''))
|
||||
} as any
|
||||
await handler({} as any)
|
||||
|
||||
expect(consoleLogSpy.mock.calls).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('it should install tagged version if cli is tagged with latest', async () => {
|
||||
setFetchSpec('latest');
|
||||
(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve(args))
|
||||
setFetchSpec('latest')
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue(args)
|
||||
// @ts-expect-error
|
||||
fs.promises = { writeFile: jest.fn()
|
||||
fs.promises = { writeFile: vi.fn()
|
||||
.mockReturnValue(Promise.resolve('')) }
|
||||
await handler({} as any)
|
||||
|
||||
|
|
@ -162,10 +181,10 @@ describe('install compliant NPM tag packages', () => {
|
|||
})
|
||||
|
||||
test('it should not install tagged version if cli is tagged with a specific version', async () => {
|
||||
setFetchSpec('7.0.8');
|
||||
(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve(args))
|
||||
setFetchSpec('7.0.8')
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue(args)
|
||||
// @ts-expect-error
|
||||
fs.promises = { writeFile: jest.fn()
|
||||
fs.promises = { writeFile: vi.fn()
|
||||
.mockReturnValue(Promise.resolve('')) }
|
||||
await handler({} as any)
|
||||
|
||||
|
|
@ -179,7 +198,7 @@ describe('install compliant NPM tag packages', () => {
|
|||
})
|
||||
|
||||
test('prints TypeScript setup message', async () => {
|
||||
(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve({
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue({
|
||||
framework: '@wdio/mocha-framework$--$mocha',
|
||||
reporters: [],
|
||||
plugins: [],
|
||||
|
|
@ -190,14 +209,14 @@ test('prints TypeScript setup message', async () => {
|
|||
generateTestFiles: false,
|
||||
isUsingCompiler: 'TypeScript (https://www.typescriptlang.org/)',
|
||||
npmInstall: true
|
||||
}))
|
||||
})
|
||||
await handler({} as any)
|
||||
expect(consoleLogSpy.mock.calls).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('prints TypeScript setup message with ts-node installed', async () => {
|
||||
process.env.WDIO_TEST_THROW_RESOLVE = '1'
|
||||
;(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve({
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue({
|
||||
framework: '@wdio/mocha-framework$--$mocha',
|
||||
reporters: [],
|
||||
plugins: [],
|
||||
|
|
@ -208,7 +227,7 @@ test('prints TypeScript setup message with ts-node installed', async () => {
|
|||
generateTestFiles: false,
|
||||
isUsingCompiler: 'TypeScript (https://www.typescriptlang.org/)',
|
||||
npmInstall: true
|
||||
}))
|
||||
})
|
||||
|
||||
const config = {
|
||||
compilerOptions: {
|
||||
|
|
@ -228,7 +247,7 @@ test('prints TypeScript setup message with ts-node installed', async () => {
|
|||
JSON.stringify(config, null, 4))
|
||||
|
||||
// @ts-expect-error
|
||||
fs.promises = { writeFile: jest.fn()
|
||||
fs.promises = { writeFile: vi.fn()
|
||||
.mockReturnValue(Promise.resolve('')) }
|
||||
await handler({} as any)
|
||||
expect(consoleLogSpy.mock.calls).toMatchSnapshot()
|
||||
|
|
@ -236,7 +255,7 @@ test('prints TypeScript setup message with ts-node installed', async () => {
|
|||
|
||||
test('should setup Babel if not existing', async () => {
|
||||
process.env.WDIO_TEST_THROW_RESOLVE = '1'
|
||||
;(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve({
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue({
|
||||
framework: '@wdio/mocha-framework$--$mocha',
|
||||
reporters: [],
|
||||
plugins: [],
|
||||
|
|
@ -247,9 +266,9 @@ test('should setup Babel if not existing', async () => {
|
|||
generateTestFiles: false,
|
||||
isUsingCompiler: 'Babel (https://babeljs.io/)',
|
||||
npmInstall: true
|
||||
}))
|
||||
})
|
||||
// @ts-expect-error
|
||||
fs.promises = { writeFile: jest.fn()
|
||||
fs.promises = { writeFile: vi.fn()
|
||||
.mockReturnValue(Promise.resolve('')) }
|
||||
await handler({} as any)
|
||||
expect(consoleLogSpy.mock.calls).toMatchSnapshot()
|
||||
|
|
@ -257,7 +276,7 @@ test('should setup Babel if not existing', async () => {
|
|||
|
||||
test('should not install @babel/register if existing', async () => {
|
||||
delete process.env.WDIO_TEST_THROW_RESOLVE
|
||||
;(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve({
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue({
|
||||
framework: '@wdio/mocha-framework$--$mocha',
|
||||
reporters: [],
|
||||
plugins: [],
|
||||
|
|
@ -268,14 +287,14 @@ test('should not install @babel/register if existing', async () => {
|
|||
generateTestFiles: false,
|
||||
isUsingCompiler: 'Babel (https://babeljs.io/)',
|
||||
npmInstall: true
|
||||
}))
|
||||
})
|
||||
await handler({} as any)
|
||||
expect(consoleLogSpy.mock.calls).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('should not install npm packages when npmInstall is false', async () => {
|
||||
const ans = { ...args, npmInstall: false };
|
||||
(inquirer.prompt as any as jest.Mock).mockReturnValue(Promise.resolve(ans))
|
||||
const ans = { ...args, npmInstall: false }
|
||||
vi.mocked(inquirer.prompt).mockResolvedValue(ans)
|
||||
await handler({} as any)
|
||||
expect(consoleLogSpy).toMatchSnapshot()
|
||||
expect(yarnInstall).not.toHaveBeenCalled()
|
||||
|
|
@ -283,25 +302,25 @@ test('should not install npm packages when npmInstall is false', async () => {
|
|||
|
||||
describe('missingConfigurationPromp', () => {
|
||||
it('should prompt user', async () => {
|
||||
(inquirer.prompt as any as jest.Mock).mockImplementation(() => ({ config: true }))
|
||||
await missingConfigurationPrompt('run', 'foobar', false, jest.fn())
|
||||
expect((inquirer.prompt as any as jest.Mock)).toHaveBeenCalled()
|
||||
vi.mocked(inquirer.prompt).mockImplementation(() => ({ config: true }) as any)
|
||||
await missingConfigurationPrompt('run', 'foobar', false, vi.fn())
|
||||
expect(vi.mocked(inquirer.prompt)).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should call function to initalize configuration helper', async () => {
|
||||
const runConfig = jest.fn()
|
||||
const runConfig = vi.fn()
|
||||
await missingConfigurationPrompt('test', 'foobar', false, runConfig)
|
||||
expect(runConfig).toHaveBeenCalledWith(false, false, true)
|
||||
})
|
||||
|
||||
it('should pass "yarn" flag to runConfig', async () => {
|
||||
const runConfig = jest.fn()
|
||||
const runConfig = vi.fn()
|
||||
await missingConfigurationPrompt('test', 'test message', true, runConfig)
|
||||
expect(runConfig).toHaveBeenCalledWith(true, false, true)
|
||||
})
|
||||
|
||||
it('should throw if error occurs', async () => {
|
||||
const runConfig = jest.fn().mockImplementation(Promise.reject)
|
||||
const runConfig = vi.fn().mockImplementation(Promise.reject)
|
||||
|
||||
try {
|
||||
await missingConfigurationPrompt('test', 'foobar', false, runConfig)
|
||||
|
|
@ -311,6 +330,6 @@ describe('missingConfigurationPromp', () => {
|
|||
})
|
||||
|
||||
afterEach(() => {
|
||||
(inquirer.prompt as any as jest.Mock).mockClear()
|
||||
vi.mocked(inquirer.prompt).mockClear()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import path from 'node:path'
|
||||
import { vi, describe, it, expect, afterEach, beforeEach } from 'vitest'
|
||||
// @ts-expect-error mock
|
||||
import { yargs } from 'yargs/yargs'
|
||||
import fs from 'fs-extra'
|
||||
|
|
@ -6,20 +8,20 @@ import * as configCmd from '../../src/commands/config'
|
|||
import * as utils from '../../src/utils'
|
||||
import yarnInstall from 'yarn-install'
|
||||
|
||||
jest.mock('yarn-install')
|
||||
jest.mock('fs-extra')
|
||||
vi.mock('yargs/yargs')
|
||||
vi.mock('yarn-install')
|
||||
vi.mock('fs-extra')
|
||||
vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger')))
|
||||
|
||||
let findInConfigMock: jest.SpyInstance
|
||||
const findInConfigMock = vi.spyOn(utils, 'findInConfig')
|
||||
|
||||
describe('Command: install', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(console, 'log')
|
||||
jest.spyOn(process, 'exit').mockImplementation((code?: number): never => code as never)
|
||||
jest.spyOn(configCmd, 'missingConfigurationPrompt').mockImplementation(() => Promise.resolve() as any)
|
||||
jest.spyOn(utils, 'addServiceDeps')
|
||||
jest.spyOn(utils, 'replaceConfig').mockReturnValueOnce({ foo: 123 } as any)
|
||||
|
||||
findInConfigMock = jest.spyOn(utils, 'findInConfig')
|
||||
vi.spyOn(console, 'log')
|
||||
vi.spyOn(process, 'exit').mockImplementation((code?: number): never => code as never)
|
||||
vi.spyOn(configCmd, 'missingConfigurationPrompt').mockImplementation(() => Promise.resolve() as any)
|
||||
vi.spyOn(utils, 'addServiceDeps')
|
||||
vi.spyOn(utils, 'replaceConfig').mockReturnValueOnce({ foo: 123 } as any)
|
||||
})
|
||||
|
||||
it('it should properly build command', () => {
|
||||
|
|
@ -45,8 +47,8 @@ describe('Command: install', () => {
|
|||
})
|
||||
|
||||
it('should prompt missing configuration', async () => {
|
||||
jest.spyOn(configCmd, 'missingConfigurationPrompt').mockImplementation(() => Promise.reject())
|
||||
;(fs.existsSync as jest.Mock).mockReturnValue(false)
|
||||
vi.spyOn(configCmd, 'missingConfigurationPrompt').mockImplementation(() => Promise.reject())
|
||||
vi.mocked(fs.existsSync).mockReturnValue(false)
|
||||
|
||||
await installCmd.handler({ type: 'service', name: 'chromedriver', config: './wdio.conf.js' } as any)
|
||||
|
||||
|
|
@ -56,7 +58,7 @@ You can create one by running 'wdio config'`, undefined)
|
|||
|
||||
it('should verify if configuration already has desired installation', async () => {
|
||||
findInConfigMock.mockReturnValue(['chromedriver'])
|
||||
;(fs.existsSync as jest.Mock).mockReturnValue(true)
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
|
||||
await installCmd.handler({ type: 'service', name: 'chromedriver', config: './wdio.conf.js' } as any)
|
||||
|
||||
|
|
@ -65,9 +67,9 @@ You can create one by running 'wdio config'`, undefined)
|
|||
|
||||
it('should correctly install packages', async () => {
|
||||
findInConfigMock.mockReturnValue([''])
|
||||
;(fs.existsSync as jest.Mock).mockReturnValue(true)
|
||||
;(fs.readFileSync as jest.Mock).mockReturnValue('module.config = {}')
|
||||
;(yarnInstall as any as jest.Mock).mockImplementation(() => ({ status: 0 }))
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('module.config = {}')
|
||||
vi.mocked(yarnInstall).mockImplementation(() => ({ status: 0 }) as any)
|
||||
|
||||
await installCmd.handler({ type: 'service', name: 'chromedriver', config: './wdio.conf.js' } as any)
|
||||
|
||||
|
|
@ -81,10 +83,10 @@ You can create one by running 'wdio config'`, undefined)
|
|||
|
||||
it('should fail if config could not be updated', async () => {
|
||||
findInConfigMock.mockReturnValue([''])
|
||||
;(fs.readFileSync as jest.Mock).mockReturnValue('module.config = {}')
|
||||
;(yarnInstall as any as jest.Mock).mockImplementation(() => ({ status: 0 }))
|
||||
;(utils.replaceConfig as jest.Mock).mockRestore()
|
||||
jest.spyOn(utils, 'replaceConfig').mockReturnValue('')
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('module.config = {}')
|
||||
vi.mocked(yarnInstall).mockImplementation(() => ({ status: 0 }) as any)
|
||||
vi.mocked(utils.replaceConfig).mockRestore()
|
||||
vi.spyOn(utils, 'replaceConfig').mockReturnValue('')
|
||||
|
||||
const err = await installCmd.handler({ type: 'service', name: 'chromedriver', config: './wdio.conf.js' } as any)
|
||||
.catch((err: Error) => err) as Error
|
||||
|
|
@ -94,9 +96,9 @@ You can create one by running 'wdio config'`, undefined)
|
|||
|
||||
it('allows for custom config location', async () => {
|
||||
findInConfigMock.mockReturnValue([''])
|
||||
;(fs.existsSync as jest.Mock).mockReturnValue(true)
|
||||
;(fs.readFileSync as jest.Mock).mockReturnValue('module.config = {}')
|
||||
;(yarnInstall as any as jest.Mock).mockImplementation(() => ({ status: 0 }))
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('module.config = {}')
|
||||
vi.mocked(yarnInstall).mockImplementation(() => ({ status: 0 }) as any)
|
||||
|
||||
await installCmd.handler({ type: 'service', name: 'chromedriver', config: './path/to/wdio.conf.js' } as any)
|
||||
|
||||
|
|
@ -110,9 +112,9 @@ You can create one by running 'wdio config'`, undefined)
|
|||
|
||||
it('should exit if there is an error while installing', async () => {
|
||||
findInConfigMock.mockReturnValue([''])
|
||||
;(fs.existsSync as jest.Mock).mockReturnValue(true)
|
||||
;(yarnInstall as any as jest.Mock).mockImplementation(() => ({ status: 1, stderr: 'test error' }))
|
||||
jest.spyOn(console, 'error')
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
vi.mocked(yarnInstall).mockImplementation(() => ({ status: 1, stderr: 'test error' }))
|
||||
vi.spyOn(console, 'error')
|
||||
|
||||
await installCmd.handler({ type: 'service', name: 'chromedriver', config: './wdio.conf.js' } as any)
|
||||
|
||||
|
|
@ -121,15 +123,15 @@ You can create one by running 'wdio config'`, undefined)
|
|||
})
|
||||
|
||||
afterEach(() => {
|
||||
(console.log as jest.Mock).mockClear()
|
||||
;(process.exit as any as jest.Mock).mockClear()
|
||||
;(fs.readFileSync as jest.Mock).mockClear()
|
||||
;(fs.existsSync as jest.Mock).mockClear()
|
||||
;(fs.writeFileSync as jest.Mock).mockClear()
|
||||
vi.mocked(console.log).mockClear()
|
||||
vi.mocked(process.exit).mockClear()
|
||||
vi.mocked(fs.readFileSync).mockClear()
|
||||
vi.mocked(fs.existsSync).mockClear()
|
||||
vi.mocked(fs.writeFileSync).mockClear()
|
||||
|
||||
;(utils.findInConfig as jest.Mock).mockClear()
|
||||
;(utils.addServiceDeps as jest.Mock).mockClear()
|
||||
;(utils.replaceConfig as jest.Mock).mockClear()
|
||||
;(configCmd.missingConfigurationPrompt as jest.Mock).mockClear()
|
||||
vi.mocked(utils.findInConfig).mockClear()
|
||||
vi.mocked(utils.addServiceDeps).mockClear()
|
||||
vi.mocked(utils.replaceConfig).mockClear()
|
||||
vi.mocked(configCmd.missingConfigurationPrompt).mockClear()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
import path from 'node:path'
|
||||
import { vi, describe, it, expect, afterEach, beforeEach } from 'vitest'
|
||||
// @ts-expect-error mock
|
||||
import { yargs } from 'yargs/yargs'
|
||||
import { remote } from 'webdriverio'
|
||||
|
||||
import { handler, builder } from '../../src/commands/repl'
|
||||
|
||||
jest.mock('@wdio/utils', () => {
|
||||
vi.mock('@wdio/utils', () => {
|
||||
let syncSupport = false
|
||||
|
||||
return {
|
||||
setSyncSupport: (val: boolean) => (syncSupport = val),
|
||||
get hasWdioSyncSupport () {
|
||||
return syncSupport
|
||||
default: {
|
||||
setSyncSupport: (val: boolean) => (syncSupport = val),
|
||||
get hasWdioSyncSupport () {
|
||||
return syncSupport
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
jest.mock('repl')
|
||||
vi.mock('repl')
|
||||
vi.mock('yargs/yargs')
|
||||
vi.mock('webdriverio', () => import(path.join(process.cwd(), '__mocks__', 'webdriverio')))
|
||||
|
||||
describe('repl commandDir', () => {
|
||||
it('should call debug command', async () => {
|
||||
|
|
@ -44,7 +50,7 @@ describe('repl commandDir', () => {
|
|||
|
||||
describe('Command: repl', () => {
|
||||
beforeEach(() => {
|
||||
(remote as jest.Mock).mockClear()
|
||||
vi.mocked(remote).mockClear()
|
||||
})
|
||||
|
||||
it('should attach global variables', async () => {
|
||||
|
|
@ -52,6 +58,7 @@ describe('Command: repl', () => {
|
|||
|
||||
expect(global.$).not.toBeUndefined()
|
||||
expect(global.$$).not.toBeUndefined()
|
||||
// @ts-expect-error
|
||||
expect(global.browser).not.toBeUndefined()
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,54 +1,59 @@
|
|||
import { vi, describe, it, expect, afterEach, beforeEach } from 'vitest'
|
||||
// @ts-expect-error mock
|
||||
import { yargs } from 'yargs/yargs'
|
||||
import fs from 'fs-extra'
|
||||
import * as runCmd from '../../src/commands/run'
|
||||
import * as configCmd from '../../src/commands/config'
|
||||
|
||||
jest.mock('./../../src/launcher', () => class {
|
||||
run() {
|
||||
return {
|
||||
then: jest.fn().mockReturnValue({
|
||||
catch: jest.fn().mockReturnValue('launcher-mock')
|
||||
})
|
||||
vi.mock('yargs/yargs')
|
||||
vi.mock('fs-extra')
|
||||
vi.mock('./../../src/launcher', () => ({
|
||||
default: class {
|
||||
run() {
|
||||
return {
|
||||
then: vi.fn().mockReturnValue({
|
||||
catch: vi.fn().mockReturnValue('launcher-mock')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
jest.mock('./../../src/watcher', () => class {
|
||||
watch() {
|
||||
return 'watching-test'
|
||||
}))
|
||||
vi.mock('./../../src/watcher', () => ({
|
||||
default: class {
|
||||
watch() {
|
||||
return 'watching-test'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
jest.mock('fs-extra')
|
||||
}))
|
||||
|
||||
describe('Command: run', () => {
|
||||
const setEncodingMock = jest.fn()
|
||||
const onMock = jest.fn((s, c) => c())
|
||||
const setEncodingMock = vi.fn()
|
||||
const onMock = vi.fn((s, c) => c())
|
||||
|
||||
beforeEach(() => {
|
||||
(fs.existsSync as jest.Mock).mockImplementation(() => true)
|
||||
;(fs.existsSync as jest.Mock).mockClear()
|
||||
jest.spyOn(configCmd, 'missingConfigurationPrompt').mockImplementation((): Promise<never> => {
|
||||
vi.mocked(fs.existsSync).mockImplementation(() => true)
|
||||
vi.mocked(fs.existsSync).mockClear()
|
||||
vi.spyOn(configCmd, 'missingConfigurationPrompt').mockImplementation((): Promise<never> => {
|
||||
return undefined as never
|
||||
})
|
||||
jest.spyOn(console, 'error')
|
||||
jest.spyOn(process, 'openStdin').mockImplementation(
|
||||
vi.spyOn(console, 'error')
|
||||
vi.spyOn(process, 'openStdin').mockImplementation(
|
||||
() => ({ setEncoding: setEncodingMock, on: onMock }) as any)
|
||||
})
|
||||
|
||||
it('should call missingConfigurationPrompt if no config found', async () => {
|
||||
(fs.existsSync as jest.Mock).mockImplementation(() => false)
|
||||
vi.mocked(fs.existsSync).mockImplementation(() => false)
|
||||
await runCmd.handler({} as any)
|
||||
|
||||
expect(configCmd.missingConfigurationPrompt).toHaveBeenCalledTimes(1)
|
||||
expect((configCmd.missingConfigurationPrompt as jest.Mock).mock.calls[0][1])
|
||||
expect(vi.mocked(configCmd.missingConfigurationPrompt).mock.calls[0][1])
|
||||
.toContain('No WebdriverIO configuration found in "')
|
||||
|
||||
;(fs.existsSync as jest.Mock).mockClear()
|
||||
vi.mocked(fs.existsSync).mockClear()
|
||||
})
|
||||
|
||||
it('should use local conf if nothing defined', async () => {
|
||||
(fs.existsSync as jest.Mock).mockImplementation(() => true)
|
||||
vi.mocked(fs.existsSync).mockImplementation(() => true)
|
||||
await runCmd.handler({ argv: {} } as any)
|
||||
expect(fs.existsSync).toBeCalledTimes(2)
|
||||
})
|
||||
|
|
@ -90,9 +95,9 @@ describe('Command: run', () => {
|
|||
})
|
||||
|
||||
afterEach(() => {
|
||||
(process.openStdin as jest.Mock).mockReset()
|
||||
;(console.error as any as jest.Mock).mockReset()
|
||||
;(fs.existsSync as jest.Mock).mockClear()
|
||||
;(configCmd.missingConfigurationPrompt as jest.Mock).mockClear()
|
||||
vi.mocked(process.openStdin).mockReset()
|
||||
vi.mocked(console.error).mockReset()
|
||||
vi.mocked(fs.existsSync).mockClear()
|
||||
vi.mocked(configCmd.missingConfigurationPrompt).mockClear()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { test, expect } from 'vitest'
|
||||
import { getAnswers } from '../src/utils'
|
||||
|
||||
test('runConfig with yes param', async () => {
|
||||
|
|
|
|||
|
|
@ -1,36 +1,38 @@
|
|||
import { join, resolve } from 'node:path'
|
||||
import { vi, describe, it, expect, afterEach, beforeEach } from 'vitest'
|
||||
// @ts-expect-error mock
|
||||
import { yargs as yargsMock } from 'yargs/yargs'
|
||||
|
||||
import { run } from '../src/index'
|
||||
import { handler } from '../src/commands/run'
|
||||
|
||||
jest.mock('./../src/commands/run', () => ({
|
||||
...jest.requireActual('./../src/commands/run') as object,
|
||||
handler: jest.fn().mockReturnValue(Promise.resolve('success'))
|
||||
vi.mock('yargs/yargs')
|
||||
vi.mock('./../src/commands/run', async () => ({
|
||||
...(await vi.importActual('./../src/commands/run')) as object,
|
||||
handler: vi.fn().mockReturnValue(Promise.resolve('success'))
|
||||
}))
|
||||
|
||||
const consoleError = console.error
|
||||
|
||||
describe('index', () => {
|
||||
beforeEach(() => {
|
||||
(handler as jest.Mock).mockClear()
|
||||
;(yargsMock.parse as jest.Mock).mockClear()
|
||||
console.error = jest.fn()
|
||||
vi.mocked(handler).mockClear()
|
||||
vi.mocked(yargsMock.parse).mockClear()
|
||||
console.error = vi.fn()
|
||||
})
|
||||
|
||||
it('should call config if no known command is used', async () => {
|
||||
await run()
|
||||
expect((handler as jest.Mock).mock.calls[0][0]).toEqual({
|
||||
expect(vi.mocked(handler).mock.calls[0][0]).toEqual({
|
||||
configPath: join(`${process.cwd()}`, 'wdio.conf.js'),
|
||||
_: ['wdio.conf.js']
|
||||
})
|
||||
})
|
||||
|
||||
it('should set default config filename if not set', async () => {
|
||||
(yargsMock.parse as jest.Mock).mockReturnValue({ _: [], spec: ['/foo/bar'] }) as any
|
||||
vi.mocked(yargsMock.parse).mockReturnValue({ _: [], spec: ['/foo/bar'] }) as any
|
||||
await run()
|
||||
expect((handler as jest.Mock).mock.calls[0][0]).toEqual({
|
||||
expect(vi.mocked(handler).mock.calls[0][0]).toEqual({
|
||||
configPath: join(`${process.cwd()}`, 'wdio.conf.js'),
|
||||
spec: ['/foo/bar'],
|
||||
_: []
|
||||
|
|
@ -39,15 +41,15 @@ describe('index', () => {
|
|||
|
||||
it('should work properly with absolute paths', async () => {
|
||||
const expectedPath = resolve('/some/absolute/path/here/wdio.conf.js')
|
||||
;(yargsMock.parse as jest.Mock).mockReturnValue({ ...yargsMock.argv, _: [expectedPath] }) as any
|
||||
vi.mocked(yargsMock.parse).mockReturnValue({ ...yargsMock.argv, _: [expectedPath] }) as any
|
||||
await run().catch()
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(1)
|
||||
expect((handler as jest.Mock).mock.calls[0][0]).toEqual({
|
||||
expect(vi.mocked(handler).mock.calls[0][0]).toEqual({
|
||||
configPath: expectedPath,
|
||||
_: [expectedPath]
|
||||
})
|
||||
;(yargsMock.epilogue as jest.Mock).mockClear()
|
||||
vi.mocked(yargsMock.epilogue).mockClear()
|
||||
})
|
||||
|
||||
/**
|
||||
|
|
@ -55,19 +57,19 @@ describe('index', () => {
|
|||
* for some reason the `cb` variable is not the callback passed in
|
||||
*/
|
||||
it.skip('should gracefully fail', async () => {
|
||||
(yargsMock.parse as jest.Mock).mockImplementation((str, cb) => {
|
||||
vi.mocked(yargsMock.parse).mockImplementation((str: never, cb: Function) => {
|
||||
cb(null, null, 'test')
|
||||
return yargsMock.argv
|
||||
})
|
||||
;(handler as jest.Mock).mockRejectedValue(new Error('ups'))
|
||||
jest.spyOn(console, 'error')
|
||||
vi.mocked(handler).mockRejectedValue(new Error('ups'))
|
||||
vi.spyOn(console, 'error')
|
||||
|
||||
await run()
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should do nothing if command was called', async () => {
|
||||
(yargsMock.parse as jest.Mock).mockReturnValue({ ...yargsMock.argv, _: ['run'] }) as any
|
||||
vi.mocked(yargsMock.parse).mockReturnValue({ ...yargsMock.argv, _: ['run'] }) as any
|
||||
expect(typeof (await run())).toBe('undefined')
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import path from 'node:path'
|
||||
import { vi, describe, it, expect, afterEach, beforeEach } from 'vitest'
|
||||
import WDIOCLInterface from '../src/interface'
|
||||
import { HookError } from '../src/utils'
|
||||
import chalk from 'chalk'
|
||||
|
|
@ -8,13 +10,16 @@ const EMPTY_INTERFACE_MESSAGE_OBJECT = {
|
|||
debugger: {}
|
||||
}
|
||||
|
||||
vi.mock('chalk')
|
||||
vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger')))
|
||||
|
||||
describe('cli interface', () => {
|
||||
let wdioClInterface: WDIOCLInterface
|
||||
|
||||
beforeEach(() => {
|
||||
global.console.log = jest.fn()
|
||||
global.console.log = vi.fn()
|
||||
wdioClInterface = new WDIOCLInterface(config as any, 5)
|
||||
wdioClInterface.log = jest.fn().mockImplementation((...args) => args)
|
||||
wdioClInterface.log = vi.fn().mockImplementation((...args: any[]) => args)
|
||||
})
|
||||
|
||||
it('should add jobs', () => {
|
||||
|
|
@ -99,7 +104,7 @@ describe('cli interface', () => {
|
|||
})
|
||||
|
||||
it('should print test error', () => {
|
||||
wdioClInterface.onTestError = jest.fn()
|
||||
wdioClInterface.onTestError = vi.fn()
|
||||
wdioClInterface.onMessage({
|
||||
origin: 'reporter',
|
||||
name: 'printFailureMessage',
|
||||
|
|
@ -110,7 +115,7 @@ describe('cli interface', () => {
|
|||
})
|
||||
|
||||
it('should trigger job:start event on testFrameworkInit', () => {
|
||||
wdioClInterface.emit = jest.fn()
|
||||
wdioClInterface.emit = vi.fn()
|
||||
wdioClInterface.onMessage({
|
||||
name: 'testFrameworkInit',
|
||||
content: 'content'
|
||||
|
|
@ -120,7 +125,7 @@ describe('cli interface', () => {
|
|||
|
||||
it('should print reporter messages in watch mode', () => {
|
||||
wdioClInterface['_isWatchMode'] = true
|
||||
wdioClInterface.printReporters = jest.fn()
|
||||
wdioClInterface.printReporters = vi.fn()
|
||||
|
||||
wdioClInterface.onMessage({
|
||||
origin: 'reporter',
|
||||
|
|
@ -136,7 +141,7 @@ describe('cli interface', () => {
|
|||
})
|
||||
|
||||
it('should not store any other messages', () => {
|
||||
wdioClInterface.printReporters = jest.fn()
|
||||
wdioClInterface.printReporters = vi.fn()
|
||||
|
||||
expect(wdioClInterface.onMessage({
|
||||
cid: '0-0',
|
||||
|
|
@ -201,7 +206,7 @@ describe('cli interface', () => {
|
|||
|
||||
describe('setup', () => {
|
||||
it('called within constructor', () => {
|
||||
wdioClInterface.onStart = jest.fn()
|
||||
wdioClInterface.onStart = vi.fn()
|
||||
expect(wdioClInterface.result).toEqual({
|
||||
finished: 0,
|
||||
passed: 0,
|
||||
|
|
@ -212,7 +217,7 @@ describe('cli interface', () => {
|
|||
})
|
||||
|
||||
it('called explicitly', () => {
|
||||
wdioClInterface.onStart = jest.fn()
|
||||
wdioClInterface.onStart = vi.fn()
|
||||
wdioClInterface['_messages'] = {
|
||||
reporter: {},
|
||||
debugger: {}
|
||||
|
|
@ -315,22 +320,23 @@ describe('cli interface', () => {
|
|||
|
||||
scenarios.forEach(scenario => {
|
||||
it(scenario.method, () => {
|
||||
wdioClInterface.onJobComplete = jest.fn()
|
||||
wdioClInterface.onJobComplete = vi.fn()
|
||||
wdioClInterface['_jobs'].set(scenario.cid, scenario.job)
|
||||
// @ts-expect-error
|
||||
wdioClInterface[scenario.method](scenario.cid, scenario.job, scenario.retries)
|
||||
expect(wdioClInterface.onJobComplete).toBeCalledWith(scenario.cid, scenario.job, scenario.retries, scenario.message)
|
||||
})
|
||||
})
|
||||
|
||||
it('onSpecSkip', () => {
|
||||
wdioClInterface.onJobComplete = jest.fn()
|
||||
wdioClInterface.onJobComplete = vi.fn()
|
||||
wdioClInterface['_jobs'].set('cid', job)
|
||||
wdioClInterface.onSpecSkip(cid, job)
|
||||
expect(wdioClInterface.onJobComplete).toBeCalledWith(cid, job, 0, 'SKIPPED', expect.any(Function))
|
||||
})
|
||||
|
||||
it('onSpecRetry with delay', () => {
|
||||
wdioClInterface.onJobComplete = jest.fn()
|
||||
wdioClInterface.onJobComplete = vi.fn()
|
||||
wdioClInterface['_specFileRetriesDelay'] = 2
|
||||
wdioClInterface['_jobs'].set('cid', job)
|
||||
wdioClInterface.onSpecRetry(cid, job, 3)
|
||||
|
|
@ -345,10 +351,12 @@ describe('cli interface', () => {
|
|||
specs: ['bar'],
|
||||
hasTests: true
|
||||
})
|
||||
// @ts-expect-error
|
||||
expect(wdioClInterface.sigintTrigger()[0]).toContain('Ending WebDriver sessions gracefully')
|
||||
})
|
||||
|
||||
it('should print message without jobs', () => {
|
||||
// @ts-expect-error
|
||||
expect(wdioClInterface.sigintTrigger()[0]).toContain('Ended WebDriver sessions gracefully')
|
||||
})
|
||||
|
||||
|
|
@ -369,15 +377,15 @@ describe('cli interface', () => {
|
|||
wdioClInterface.printReporters()
|
||||
expect(wdioClInterface['_messages'].reporter).toEqual({})
|
||||
expect(wdioClInterface.log).toBeCalledTimes(2)
|
||||
expect((wdioClInterface.log as jest.Mock).mock.calls[0][1]).toContain('"foo" Reporter:')
|
||||
expect((wdioClInterface.log as jest.Mock).mock.calls[1][0]).toContain('bar')
|
||||
expect(vi.mocked(wdioClInterface.log).mock.calls[0][1]).toContain('"foo" Reporter:')
|
||||
expect(vi.mocked(wdioClInterface.log).mock.calls[1][0]).toContain('bar')
|
||||
})
|
||||
})
|
||||
|
||||
describe('finalise', () => {
|
||||
it('finalise should print reporters and summary', () => {
|
||||
wdioClInterface.printReporters = jest.fn()
|
||||
wdioClInterface.printSummary = jest.fn()
|
||||
wdioClInterface.printReporters = vi.fn()
|
||||
wdioClInterface.printSummary = vi.fn()
|
||||
wdioClInterface.finalise()
|
||||
expect(wdioClInterface.printReporters).toBeCalledTimes(1)
|
||||
expect(wdioClInterface.printSummary).toBeCalledTimes(1)
|
||||
|
|
@ -385,8 +393,8 @@ describe('cli interface', () => {
|
|||
|
||||
it('finalise should do nothing in watch mode', () => {
|
||||
wdioClInterface['_isWatchMode'] = true
|
||||
wdioClInterface.printReporters = jest.fn()
|
||||
wdioClInterface.printSummary = jest.fn()
|
||||
wdioClInterface.printReporters = vi.fn()
|
||||
wdioClInterface.printSummary = vi.fn()
|
||||
wdioClInterface.finalise()
|
||||
expect(wdioClInterface.printReporters).toBeCalledTimes(0)
|
||||
expect(wdioClInterface.printSummary).toBeCalledTimes(0)
|
||||
|
|
@ -423,7 +431,7 @@ describe('cli interface', () => {
|
|||
})
|
||||
})
|
||||
|
||||
test('logHookError', () => {
|
||||
it('logHookError', () => {
|
||||
const err = new HookError('foobar', 'somewhere')
|
||||
expect(wdioClInterface.logHookError(err)[0])
|
||||
.toContain('red SevereServiceError in "somewhere"')
|
||||
|
|
@ -492,6 +500,6 @@ describe('cli interface', () => {
|
|||
|
||||
afterEach(() => {
|
||||
wdioClInterface['_specFileRetriesDelay'] = 0
|
||||
;(global.console.log as jest.Mock).mockRestore()
|
||||
vi.mocked(global.console.log).mockRestore()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import path from 'node:path'
|
||||
import { vi, describe, it, expect, afterEach, beforeEach } from 'vitest'
|
||||
import Launcher from '../src/launcher'
|
||||
import logger from '@wdio/logger'
|
||||
import { sleep } from '@wdio/utils'
|
||||
|
|
@ -5,20 +7,25 @@ import fs from 'fs-extra'
|
|||
|
||||
const caps: WebDriver.DesiredCapabilities = { maxInstances: 1, browserName: 'chrome' }
|
||||
|
||||
jest.mock('fs-extra')
|
||||
jest.mock('../src/interface', () => class {
|
||||
emit = jest.fn()
|
||||
on = jest.fn()
|
||||
sigintTrigger = jest.fn()
|
||||
onMessage = jest.fn()
|
||||
})
|
||||
vi.mock('fs-extra')
|
||||
vi.mock('@wdio/utils', () => import(path.join(process.cwd(), '__mocks__', '@wdio/utils')))
|
||||
vi.mock('@wdio/config', () => import(path.join(process.cwd(), '__mocks__', '@wdio/config')))
|
||||
vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger')))
|
||||
vi.mock('../src/interface', () => ({
|
||||
default: class {
|
||||
emit = vi.fn()
|
||||
on = vi.fn()
|
||||
sigintTrigger = vi.fn()
|
||||
onMessage = vi.fn()
|
||||
}
|
||||
}))
|
||||
|
||||
describe('launcher', () => {
|
||||
const emitSpy = jest.spyOn(process, 'emit')
|
||||
const emitSpy = vi.spyOn(process, 'emit')
|
||||
let launcher: Launcher
|
||||
|
||||
beforeEach(() => {
|
||||
global.console.log = jest.fn()
|
||||
global.console.log = vi.fn()
|
||||
emitSpy.mockClear()
|
||||
launcher = new Launcher('./')
|
||||
})
|
||||
|
|
@ -50,7 +57,7 @@ describe('launcher', () => {
|
|||
|
||||
describe('capabilities', () => {
|
||||
it('should NOT fail when capabilities are passed', async () => {
|
||||
launcher.runSpecs = jest.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = vi.fn().mockReturnValue(1)
|
||||
const exitCode = await launcher.runMode({ specs: ['./'] } as any, [caps])
|
||||
expect(launcher.runSpecs).toBeCalled()
|
||||
expect(exitCode).toEqual(0)
|
||||
|
|
@ -58,15 +65,15 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should fail if no specs were found', async () => {
|
||||
launcher.runSpecs = jest.fn()
|
||||
launcher.configParser.getSpecs = jest.fn().mockReturnValue([])
|
||||
launcher.runSpecs = vi.fn()
|
||||
launcher.configParser.getSpecs = vi.fn().mockReturnValue([])
|
||||
const exitCode = await launcher.runMode({ specs: ['./'] } as any, [caps])
|
||||
expect(launcher.runSpecs).toBeCalledTimes(0)
|
||||
expect(exitCode).toBe(1)
|
||||
})
|
||||
|
||||
it('should fail when no capabilities are passed', async () => {
|
||||
launcher.runSpecs = jest.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = vi.fn().mockReturnValue(1)
|
||||
// @ts-ignore test invalid parameter
|
||||
const exitCode = await launcher.runMode({ specs: ['./'] as any })
|
||||
expect(exitCode).toEqual(1)
|
||||
|
|
@ -74,14 +81,14 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should fail when no capabilities are set', async () => {
|
||||
launcher.runSpecs = jest.fn().mockReturnValue(1)
|
||||
const exitCode = await launcher.runMode({ specs: ['./'] } as any, undefined)
|
||||
launcher.runSpecs = vi.fn().mockReturnValue(1)
|
||||
const exitCode = await launcher.runMode({ specs: ['./'] } as any, undefined as any)
|
||||
expect(exitCode).toEqual(1)
|
||||
expect(logger('').error).toBeCalledWith('Missing capabilities, exiting with failure')
|
||||
})
|
||||
|
||||
it('should start instance in multiremote', () => {
|
||||
launcher.runSpecs = jest.fn()
|
||||
launcher.runSpecs = vi.fn()
|
||||
launcher.isMultiremote = true
|
||||
launcher.runMode(
|
||||
{ specs: ['./'], specFileRetries: 2 } as any,
|
||||
|
|
@ -96,7 +103,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should start instance with grouped specs', () => {
|
||||
launcher.runSpecs = jest.fn()
|
||||
launcher.runSpecs = vi.fn()
|
||||
launcher.isMultiremote = false
|
||||
launcher.runMode(
|
||||
{ specs: [['/a.js', '/b.js']], specFileRetries: 2 } as any,
|
||||
|
|
@ -111,7 +118,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should start instance in multiremote with grouped specs', () => {
|
||||
launcher.runSpecs = jest.fn()
|
||||
launcher.runSpecs = vi.fn()
|
||||
launcher.isMultiremote = true
|
||||
launcher.runMode(
|
||||
{ specs: [['/a.js', '/b.js']], specFileRetries: 2 } as any,
|
||||
|
|
@ -126,7 +133,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should ignore specFileRetries in watch mode', () => {
|
||||
launcher.runSpecs = jest.fn()
|
||||
launcher.runSpecs = vi.fn()
|
||||
launcher['_isWatchMode'] = true
|
||||
launcher.runMode({ specs: ['./'], specFileRetries: 2 } as any, [caps, caps])
|
||||
|
||||
|
|
@ -138,7 +145,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should apply maxInstancesPerCapability if maxInstances is not passed', () => {
|
||||
launcher.runSpecs = jest.fn()
|
||||
launcher.runSpecs = vi.fn()
|
||||
launcher.runMode(
|
||||
{ specs: ['./'], specFileRetries: 3, maxInstancesPerCapability: 4 } as any,
|
||||
[{ browserName: 'chrome' }]
|
||||
|
|
@ -154,14 +161,14 @@ describe('launcher', () => {
|
|||
|
||||
describe('hasTriggeredExitRoutine', () => {
|
||||
it('should return false if there are specs left of running when hasTriggeredExitRoutine is false', () => {
|
||||
launcher.getNumberOfRunningInstances = jest.fn().mockReturnValue(1)
|
||||
launcher.getNumberOfRunningInstances = vi.fn().mockReturnValue(1)
|
||||
launcher['_hasTriggeredExitRoutine'] = false
|
||||
const returnValue = launcher.runSpecs()
|
||||
expect(returnValue).toEqual(false)
|
||||
})
|
||||
|
||||
it('should return true when hasTriggeredExitRoutine is true', () => {
|
||||
launcher.getNumberOfRunningInstances = jest.fn().mockReturnValue(1)
|
||||
launcher.getNumberOfRunningInstances = vi.fn().mockReturnValue(1)
|
||||
launcher['_hasTriggeredExitRoutine'] = true
|
||||
const returnValue = launcher.runSpecs()
|
||||
expect(returnValue).toEqual(true)
|
||||
|
|
@ -169,18 +176,18 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
describe('endHandler', () => {
|
||||
const config = { onWorkerEnd: jest.fn() }
|
||||
const config = { onWorkerEnd: vi.fn() }
|
||||
|
||||
beforeEach(() => {
|
||||
launcher['_launcher'] = []
|
||||
launcher.configParser.getConfig = jest.fn().mockReturnValue(config)
|
||||
launcher.configParser.getConfig = vi.fn().mockReturnValue(config)
|
||||
})
|
||||
|
||||
it('should emit and resolve failed status', async () => {
|
||||
launcher.getNumberOfRunningInstances = jest.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = jest.fn().mockReturnValue(1)
|
||||
launcher.getNumberOfRunningInstances = vi.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = vi.fn().mockReturnValue(1)
|
||||
launcher['_schedule'] = [{ cid: 1 } as any, { cid: 2 }]
|
||||
launcher['_resolve'] = jest.fn()
|
||||
launcher['_resolve'] = vi.fn()
|
||||
await launcher.endHandler({ cid: '0-1', exitCode: 1, specs: [], retries: 0 } as any)
|
||||
expect(launcher.interface.emit).toBeCalledWith('job:end', { cid: '0-1', passed: false, retries: 0 })
|
||||
expect(launcher['_resolve']).toBeCalledWith(1)
|
||||
|
|
@ -188,43 +195,43 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should emit and resolve passed status', async () => {
|
||||
launcher.getNumberOfRunningInstances = jest.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = jest.fn().mockReturnValue(1)
|
||||
launcher.getNumberOfRunningInstances = vi.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = vi.fn().mockReturnValue(1)
|
||||
launcher['_schedule'] = [{ cid: 1 } as any, { cid: 2 }]
|
||||
launcher['_resolve'] = jest.fn()
|
||||
launcher['_resolve'] = vi.fn()
|
||||
await launcher.endHandler({ cid: '0-1', exitCode: 0 } as any)
|
||||
expect(launcher.interface.emit).toBeCalledWith('job:end', { cid: '0-1', passed: true })
|
||||
expect(launcher['_resolve']).toBeCalledWith(0)
|
||||
})
|
||||
|
||||
it('should do nothing if not all specs are run', async () => {
|
||||
launcher.getNumberOfRunningInstances = jest.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = jest.fn().mockReturnValue(0)
|
||||
launcher.getNumberOfRunningInstances = vi.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = vi.fn().mockReturnValue(0)
|
||||
launcher['_schedule'] = [{ cid: 1 } as any, { cid: 2 }]
|
||||
launcher['_resolve'] = jest.fn()
|
||||
launcher['_resolve'] = vi.fn()
|
||||
await launcher.endHandler({ cid: '0-1', exitCode: 0 } as any)
|
||||
expect(launcher.interface.emit).toBeCalledWith('job:end', { cid: '0-1', passed: true })
|
||||
expect(launcher['_resolve']).toBeCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should do nothing if watch mode is still running', async () => {
|
||||
launcher.getNumberOfRunningInstances = jest.fn().mockReturnValue(1)
|
||||
launcher.getNumberOfRunningInstances = vi.fn().mockReturnValue(1)
|
||||
launcher['_isWatchMode'] = true
|
||||
launcher.runSpecs = jest.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = vi.fn().mockReturnValue(1)
|
||||
launcher['_schedule'] = [{ cid: 1 } as any, { cid: 2 }]
|
||||
launcher['_resolve'] = jest.fn()
|
||||
launcher['_resolve'] = vi.fn()
|
||||
await launcher.endHandler({ cid: '0-1', exitCode: 1 } as any)
|
||||
expect(launcher.interface.emit).toBeCalledWith('job:end', { cid: '0-1', passed: false })
|
||||
expect(launcher['_resolve']).toBeCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should resolve and not emit on watch mode stop', async () => {
|
||||
launcher.getNumberOfRunningInstances = jest.fn().mockReturnValue(1)
|
||||
launcher.getNumberOfRunningInstances = vi.fn().mockReturnValue(1)
|
||||
launcher['_isWatchMode'] = true
|
||||
launcher['_hasTriggeredExitRoutine'] = true
|
||||
launcher.runSpecs = jest.fn().mockReturnValue(1)
|
||||
launcher.runSpecs = vi.fn().mockReturnValue(1)
|
||||
launcher['_schedule'] = [{ cid: 1 } as any, { cid: 2 }]
|
||||
launcher['_resolve'] = jest.fn()
|
||||
launcher['_resolve'] = vi.fn()
|
||||
await launcher.endHandler({ cid: '0-1', exitCode: 1 } as any)
|
||||
expect(launcher.interface.emit).not.toBeCalled()
|
||||
expect(launcher['_resolve']).toBeCalledWith(0)
|
||||
|
|
@ -237,7 +244,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should requeue retried specfiles at beginning of queue', async () => {
|
||||
launcher.configParser.getConfig = jest.fn().mockReturnValue({ specFileRetriesDeferred: false, onWorkerEnd: jest.fn() })
|
||||
launcher.configParser.getConfig = vi.fn().mockReturnValue({ specFileRetriesDeferred: false, onWorkerEnd: vi.fn() })
|
||||
launcher['_schedule'] = [{ cid: 0, specs: [{ files: ['b.js'] }] }] as any
|
||||
await launcher.endHandler({ cid: '0-5', exitCode: 1, retries: 1, specs: ['a.js'] })
|
||||
expect(launcher['_schedule']).toMatchObject([{ cid: 0, specs: [{ rid: '0-5', files: ['a.js'], retries: 0 }, { files: ['b.js'] }] }])
|
||||
|
|
@ -253,36 +260,36 @@ describe('launcher', () => {
|
|||
describe('exitHandler', () => {
|
||||
it('should do nothing if no callback is given', () => {
|
||||
launcher['_hasTriggeredExitRoutine'] = false
|
||||
launcher.runner = { shutdown: jest.fn()
|
||||
launcher.runner = { shutdown: vi.fn()
|
||||
.mockReturnValue(Promise.resolve()) } as any
|
||||
|
||||
launcher.exitHandler()
|
||||
|
||||
expect(launcher['_hasTriggeredExitRoutine']).toBe(false)
|
||||
expect(launcher.interface.sigintTrigger).toBeCalledTimes(0)
|
||||
expect(launcher.runner.shutdown).toBeCalledTimes(0)
|
||||
expect(launcher.runner?.shutdown).toBeCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should do nothing if shutdown was called before', () => {
|
||||
launcher['_hasTriggeredExitRoutine'] = true
|
||||
launcher.runner = { shutdown: jest.fn().mockReturnValue(Promise.resolve()) } as any
|
||||
launcher.runner = { shutdown: vi.fn().mockReturnValue(Promise.resolve()) } as any
|
||||
|
||||
expect(launcher.exitHandler(() => 'foo')).toBe('foo')
|
||||
|
||||
expect(launcher['_hasTriggeredExitRoutine']).toBe(true)
|
||||
expect(launcher.interface.sigintTrigger).toBeCalledTimes(0)
|
||||
expect(launcher.runner.shutdown).toBeCalledTimes(0)
|
||||
expect(launcher.runner?.shutdown).toBeCalledTimes(0)
|
||||
})
|
||||
|
||||
it('should shutdown', () => {
|
||||
launcher['_hasTriggeredExitRoutine'] = false
|
||||
launcher.runner = { shutdown: jest.fn().mockReturnValue(Promise.resolve()) } as any
|
||||
launcher.runner = { shutdown: vi.fn().mockReturnValue(Promise.resolve()) } as any
|
||||
|
||||
launcher.exitHandler(jest.fn())
|
||||
launcher.exitHandler(vi.fn())
|
||||
|
||||
expect(launcher['_hasTriggeredExitRoutine']).toBe(true)
|
||||
expect(launcher.interface.sigintTrigger).toBeCalledTimes(1)
|
||||
expect(launcher.runner.shutdown).toBeCalledTimes(1)
|
||||
expect(launcher.runner?.shutdown).toBeCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -325,7 +332,7 @@ describe('launcher', () => {
|
|||
]
|
||||
// Mock the return value of getSpecs so we are not doing cross
|
||||
// module testing
|
||||
launcher.configParser = { getSpecs: jest.fn().mockReturnValue(
|
||||
launcher.configParser = { getSpecs: vi.fn().mockReturnValue(
|
||||
['/a.js', ['/b.js', '/c.js', '/d.js'], '/e.js']
|
||||
) } as any
|
||||
expect(launcher.formatSpecs(capabilities as any, specFileRetries)).toStrictEqual(expected)
|
||||
|
|
@ -334,11 +341,11 @@ describe('launcher', () => {
|
|||
|
||||
describe('runSpecs', () => {
|
||||
beforeEach(() => {
|
||||
launcher.startInstance = jest.fn()
|
||||
launcher.startInstance = vi.fn()
|
||||
})
|
||||
|
||||
it('should not start running anything if exit routine is triggered', () => {
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
maxInstances: 100
|
||||
}) } as any
|
||||
launcher['_hasTriggeredExitRoutine'] = true
|
||||
|
|
@ -347,7 +354,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should run all specs', () => {
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
maxInstances: 100
|
||||
}) } as any
|
||||
launcher['_schedule'] = [{
|
||||
|
|
@ -384,7 +391,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should run arrayed specs in a single instance', () => {
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
maxInstances: 100
|
||||
}) } as any
|
||||
launcher['_schedule'] = [{
|
||||
|
|
@ -422,7 +429,7 @@ describe('launcher', () => {
|
|||
|
||||
it('should not run anything if runner failed', () => {
|
||||
launcher['_runnerFailed'] = 2
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
maxInstances: 100,
|
||||
bail: 1
|
||||
}) } as any
|
||||
|
|
@ -454,7 +461,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should run as much as maxInstances allows', () => {
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
maxInstances: 5
|
||||
}) } as any
|
||||
launcher['_schedule'] = [{
|
||||
|
|
@ -485,7 +492,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should not allow to schedule more runner if no instances are available', () => {
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
maxInstances: 100
|
||||
}) } as any
|
||||
launcher['_schedule'] = [{
|
||||
|
|
@ -522,7 +529,7 @@ describe('launcher', () => {
|
|||
})
|
||||
|
||||
it('should not run if all specs were executed', () => {
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
maxInstances: 100
|
||||
}) } as any
|
||||
launcher['_schedule'] = [{
|
||||
|
|
@ -541,12 +548,17 @@ describe('launcher', () => {
|
|||
|
||||
describe('startInstance', () => {
|
||||
beforeEach(() => {
|
||||
(launcher.runner.run as jest.Mock) = jest.fn().mockReturnValue({ on: () => {} })
|
||||
// launcher.runner?.run = vi.fn().mockReturnValue({ on: () => {} })
|
||||
launcher['_launcher'] = []
|
||||
launcher.runner = {
|
||||
run: vi.fn().mockReturnValue({
|
||||
on: vi.fn()
|
||||
})
|
||||
} as any
|
||||
})
|
||||
|
||||
it('should start an instance', async () => {
|
||||
const onWorkerStartMock = jest.fn()
|
||||
const onWorkerStartMock = vi.fn()
|
||||
const caps = {
|
||||
browserName: 'chrome'
|
||||
}
|
||||
|
|
@ -564,7 +576,7 @@ describe('launcher', () => {
|
|||
|
||||
expect(sleep).not.toHaveBeenCalled()
|
||||
expect(launcher['_runnerStarted']).toBe(1)
|
||||
expect((launcher.runner.run as jest.Mock).mock.calls[0][0]).toHaveProperty('cid', '0-5')
|
||||
expect(vi.mocked(launcher.runner?.run!).mock.calls[0][0]).toHaveProperty('cid', '0-5')
|
||||
expect(launcher.getRunnerId(0)).toBe('0-0')
|
||||
|
||||
expect(onWorkerStartMock).toHaveBeenCalledWith(
|
||||
|
|
@ -572,16 +584,16 @@ describe('launcher', () => {
|
|||
caps,
|
||||
['/foo.test.js'],
|
||||
{ hostname: '127.0.0.2' },
|
||||
['--no-wasm-code-gc']
|
||||
[]
|
||||
)
|
||||
})
|
||||
|
||||
it('should wait before starting an instance on retry', async () => {
|
||||
const onWorkerStartMock = jest.fn()
|
||||
const onWorkerStartMock = vi.fn()
|
||||
const caps = {
|
||||
browserName: 'chrome'
|
||||
}
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
onWorkerStart: onWorkerStartMock,
|
||||
specFileRetries: 2,
|
||||
specFileRetriesDelay: 0.01
|
||||
|
|
@ -604,16 +616,16 @@ describe('launcher', () => {
|
|||
caps,
|
||||
['/foo.test.js'],
|
||||
{ hostname: '127.0.0.3' },
|
||||
['--no-wasm-code-gc']
|
||||
[]
|
||||
)
|
||||
})
|
||||
|
||||
it('should not wait before starting an instance on the first run', async () => {
|
||||
const onWorkerStartMock = jest.fn()
|
||||
const onWorkerStartMock = vi.fn()
|
||||
const caps = {
|
||||
browserName: 'chrome'
|
||||
}
|
||||
launcher.configParser = { getConfig: jest.fn().mockReturnValue({
|
||||
launcher.configParser = { getConfig: vi.fn().mockReturnValue({
|
||||
onWorkerStart: onWorkerStartMock,
|
||||
specFileRetries: 4,
|
||||
specFileRetriesDelay: 0.01
|
||||
|
|
@ -635,22 +647,18 @@ describe('launcher', () => {
|
|||
caps,
|
||||
['/foo.test.js'],
|
||||
{ hostname: '127.0.0.4' },
|
||||
['--no-wasm-code-gc']
|
||||
[]
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('config options', () => {
|
||||
let ensureDirSyncSpy: any
|
||||
beforeEach(() => {
|
||||
ensureDirSyncSpy = jest.spyOn(fs, 'ensureDirSync')
|
||||
})
|
||||
it('should create directory when the config options have a outputDir option', () => {
|
||||
expect(ensureDirSyncSpy).toHaveBeenCalled()
|
||||
expect(ensureDirSyncSpy).toHaveBeenCalledWith('tempDir')
|
||||
expect(vi.mocked(fs.ensureDirSync)).toHaveBeenCalled()
|
||||
expect(vi.mocked(fs.ensureDirSync)).toHaveBeenCalledWith('tempDir')
|
||||
})
|
||||
afterEach(() => {
|
||||
ensureDirSyncSpy.mockClear()
|
||||
vi.mocked(fs.ensureDirSync).mockClear()
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -658,33 +666,36 @@ describe('launcher', () => {
|
|||
let config: WebdriverIO.Config = { capabilities: {} }
|
||||
|
||||
beforeEach(() => {
|
||||
global.console.error = jest.fn()
|
||||
global.console.error = vi.fn()
|
||||
|
||||
config = {
|
||||
// ConfigParser.addFileConfig() will return onPrepare and onComplete as arrays of functions
|
||||
onPrepare: [jest.fn()],
|
||||
onComplete: [jest.fn()],
|
||||
capabilities: {}
|
||||
onPrepare: [vi.fn()],
|
||||
onComplete: [vi.fn()],
|
||||
capabilities: {},
|
||||
runner: 'local'
|
||||
}
|
||||
launcher.configParser = {
|
||||
getCapabilities: jest.fn().mockReturnValue(0),
|
||||
getConfig: jest.fn().mockReturnValue(config),
|
||||
autoCompile: jest.fn()
|
||||
getCapabilities: vi.fn().mockReturnValue(0),
|
||||
getConfig: vi.fn().mockReturnValue(config),
|
||||
autoCompile: vi.fn()
|
||||
} as any
|
||||
launcher.runner = { initialise: jest.fn(), shutdown: jest.fn() } as any
|
||||
launcher.runMode = jest.fn().mockImplementation((config, caps) => caps)
|
||||
launcher.interface = { finalise: jest.fn() } as any
|
||||
launcher.runner = { initialise: vi.fn(), shutdown: vi.fn() } as any
|
||||
launcher.runMode = vi.fn().mockImplementation((config, caps) => caps)
|
||||
launcher.interface = { finalise: vi.fn() } as any
|
||||
})
|
||||
|
||||
it('exit code 0', async () => {
|
||||
expect(await launcher.run()).toEqual(0)
|
||||
expect(launcher.runner.shutdown).toBeCalled()
|
||||
expect(launcher.runner!.shutdown).toBeCalled()
|
||||
|
||||
expect(launcher.configParser.getCapabilities).toBeCalledTimes(1)
|
||||
expect(launcher.configParser.getConfig).toBeCalledTimes(1)
|
||||
expect(launcher.runner.initialise).toBeCalledTimes(1)
|
||||
expect(launcher.runner!.initialise).toBeCalledTimes(1)
|
||||
// @ts-expect-error
|
||||
expect(config.onPrepare[0]).toBeCalledTimes(1)
|
||||
expect(launcher.runMode).toBeCalledTimes(1)
|
||||
// @ts-expect-error
|
||||
expect(config.onPrepare[0]).toBeCalledTimes(1)
|
||||
expect(launcher.interface.finalise).toBeCalledTimes(1)
|
||||
})
|
||||
|
|
@ -692,7 +703,7 @@ describe('launcher', () => {
|
|||
it('should not shutdown runner if was called before', async () => {
|
||||
launcher['_hasTriggeredExitRoutine'] = true
|
||||
expect(await launcher.run()).toEqual(0)
|
||||
expect(launcher.runner.shutdown).not.toBeCalled()
|
||||
expect(launcher.runner!.shutdown).not.toBeCalled()
|
||||
})
|
||||
|
||||
it('onComplete error', async () => {
|
||||
|
|
@ -700,10 +711,11 @@ describe('launcher', () => {
|
|||
config.onComplete = [() => { throw new Error() }]
|
||||
|
||||
expect(await launcher.run()).toEqual(1)
|
||||
expect(launcher.runner.shutdown).toBeCalled()
|
||||
expect(launcher.runner!.shutdown).toBeCalled()
|
||||
})
|
||||
|
||||
it('should shutdown runner on error', async () => {
|
||||
// @ts-expect-error
|
||||
delete logger.waitForBuffer
|
||||
|
||||
let error
|
||||
|
|
@ -712,17 +724,17 @@ describe('launcher', () => {
|
|||
} catch (err: any) {
|
||||
error = err
|
||||
}
|
||||
expect(launcher.runner.shutdown).toBeCalled()
|
||||
expect(launcher.runner!.shutdown).toBeCalled()
|
||||
expect(error).toBeInstanceOf(Error)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
(global.console.error as jest.Mock).mockRestore()
|
||||
vi.mocked(global.console.error).mockRestore()
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
(global.console.log as jest.Mock).mockRestore()
|
||||
;(sleep as jest.Mock).mockClear()
|
||||
vi.mocked(global.console.log).mockRestore()
|
||||
vi.mocked(sleep).mockClear()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,40 +1,43 @@
|
|||
import { vi, describe, it, expect, afterEach, beforeEach } from 'vitest'
|
||||
import { launch, cmdArgs } from '../src/commands/run'
|
||||
import Launcher from '../src/launcher'
|
||||
|
||||
jest.mock('../src/launcher', () => jest.fn().mockImplementation((conf, result) => ({
|
||||
run: () => Number.isInteger(result) ? Promise.resolve(result) : Promise.reject(result)
|
||||
})))
|
||||
vi.mock('../src/launcher', () => ({
|
||||
default: vi.fn().mockImplementation((conf, result) => ({
|
||||
run: () => Number.isInteger(result) ? Promise.resolve(result) : Promise.reject(result)
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('launch', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {})
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
})
|
||||
|
||||
it('should exit with code 0', async () => {
|
||||
// @ts-ignore mock feature
|
||||
await launch('configFile', 0)
|
||||
expect(Launcher).toBeCalledWith('configFile', 0)
|
||||
expect((Launcher as jest.Mock).mock.instances).toHaveLength(1)
|
||||
expect(vi.mocked(Launcher).mock.instances).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('should exit with code 1', async () => {
|
||||
// @ts-ignore mock feature
|
||||
await launch('configFile', 1)
|
||||
expect(Launcher).toBeCalledWith('configFile', 1)
|
||||
expect((Launcher as jest.Mock).mock.instances).toHaveLength(1)
|
||||
expect(vi.mocked(Launcher).mock.instances).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('should catch errors', async () => {
|
||||
// @ts-ignore mock feature
|
||||
await launch('configFile', 'foobar')
|
||||
expect(Launcher).toBeCalledWith('configFile', 'foobar')
|
||||
expect((Launcher as jest.Mock).mock.instances).toHaveLength(1)
|
||||
expect(vi.mocked(Launcher).mock.instances).toHaveLength(1)
|
||||
expect(console.error).toBeCalledWith('foobar')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
(Launcher as jest.Mock).mockClear()
|
||||
;(console.error as jest.Mock).mockRestore()
|
||||
vi.mocked(Launcher).mockClear()
|
||||
vi.mocked(console.error).mockRestore()
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import { vi, describe, it, expect, afterEach, beforeEach, test } from 'vitest'
|
||||
import path from 'node:path'
|
||||
import fs from 'fs-extra'
|
||||
import ejs from 'ejs'
|
||||
import readDirMock from 'recursive-readdir'
|
||||
import childProcess from 'node:child_process'
|
||||
import readDir from 'recursive-readdir'
|
||||
// @ts-ignore mock feature
|
||||
import { execSyncRes } from 'node:child_process'
|
||||
import { SevereServiceError } from 'webdriverio'
|
||||
import { ConfigParser } from '@wdio/config'
|
||||
|
||||
const readDir = readDirMock as jest.Mock
|
||||
|
||||
import {
|
||||
runLauncherHook,
|
||||
runOnCompleteHook,
|
||||
|
|
@ -27,7 +28,10 @@ import {
|
|||
} from '../src/utils'
|
||||
import { COMPILER_OPTION_ANSWERS } from '../src/constants'
|
||||
|
||||
jest.mock('child_process', function () {
|
||||
vi.mock('ejs')
|
||||
vi.mock('recursive-readdir')
|
||||
vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger')))
|
||||
vi.mock('child_process', function () {
|
||||
const m = {
|
||||
execSyncRes: 'APPIUM_MISSING',
|
||||
execSync: function () { return m.execSyncRes }
|
||||
|
|
@ -35,15 +39,17 @@ jest.mock('child_process', function () {
|
|||
return m
|
||||
})
|
||||
|
||||
jest.mock('../src/commands/config', () => ({
|
||||
runConfig: jest.fn()
|
||||
vi.mock('../src/commands/config', () => ({
|
||||
runConfig: vi.fn()
|
||||
}))
|
||||
|
||||
jest.mock('fs-extra', () => ({
|
||||
existsSync: jest.fn(),
|
||||
ensureDirSync: jest.fn(),
|
||||
promises: {
|
||||
writeFile: jest.fn().mockReturnValue(Promise.resolve())
|
||||
vi.mock('fs-extra', () => ({
|
||||
default: {
|
||||
existsSync: vi.fn(),
|
||||
ensureDirSync: vi.fn(),
|
||||
promises: {
|
||||
writeFile: vi.fn().mockReturnValue(Promise.resolve())
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
|
|
@ -51,7 +57,7 @@ jest.mock('fs-extra', () => ({
|
|||
* it is necessary here to create a new mock for the ConfigParser because it
|
||||
* doesn't seem to be possible to spy on jest mock instances
|
||||
*/
|
||||
jest.mock('@wdio/config', () => ({
|
||||
vi.mock('@wdio/config', () => ({
|
||||
ConfigParser: class ConfigParserMock {
|
||||
addConfigFile () {}
|
||||
autoCompile () {}
|
||||
|
|
@ -60,13 +66,13 @@ jest.mock('@wdio/config', () => ({
|
|||
}))
|
||||
|
||||
beforeEach(() => {
|
||||
global.console.log = jest.fn()
|
||||
global.console.log = vi.fn()
|
||||
})
|
||||
|
||||
describe('runServiceHook', () => {
|
||||
const hookSuccess = jest.fn()
|
||||
const slowSetupFn = jest.fn()
|
||||
const asyncHookSuccess = jest.fn().mockImplementation(() => new Promise<void>(resolve => {
|
||||
const hookSuccess = vi.fn()
|
||||
const slowSetupFn = vi.fn()
|
||||
const asyncHookSuccess = vi.fn().mockImplementation(() => new Promise<void>(resolve => {
|
||||
setTimeout(() => {
|
||||
slowSetupFn()
|
||||
resolve()
|
||||
|
|
@ -79,7 +85,7 @@ describe('runServiceHook', () => {
|
|||
asyncHookSuccess.mockClear()
|
||||
})
|
||||
|
||||
test('run sync and async hooks successfully', async () => {
|
||||
it('run sync and async hooks successfully', async () => {
|
||||
await runServiceHook([
|
||||
{ onPrepare: hookSuccess },
|
||||
{ onPrepare: asyncHookSuccess },
|
||||
|
|
@ -92,7 +98,7 @@ describe('runServiceHook', () => {
|
|||
})
|
||||
|
||||
it('executes all hooks and continues after a hook throws error', async () => {
|
||||
const hookFailing = jest.fn().mockImplementation(() => { throw new Error('buhh') })
|
||||
const hookFailing = vi.fn().mockImplementation(() => { throw new Error('buhh') })
|
||||
|
||||
await runServiceHook([
|
||||
{ onPrepare: hookSuccess },
|
||||
|
|
@ -109,7 +115,7 @@ describe('runServiceHook', () => {
|
|||
})
|
||||
|
||||
it('executes all hooks and stops after a hook throws SevereServiceError', async () => {
|
||||
const hookFailing = jest.fn().mockImplementation(() => { throw new SevereServiceError() })
|
||||
const hookFailing = vi.fn().mockImplementation(() => { throw new SevereServiceError() })
|
||||
|
||||
try {
|
||||
await runServiceHook([
|
||||
|
|
@ -131,8 +137,8 @@ describe('runServiceHook', () => {
|
|||
})
|
||||
|
||||
test('runLauncherHook handles array of functions', () => {
|
||||
const hookSuccess = jest.fn()
|
||||
const hookFailing = jest.fn().mockImplementation(() => { throw new Error('buhh') })
|
||||
const hookSuccess = vi.fn()
|
||||
const hookFailing = vi.fn().mockImplementation(() => { throw new Error('buhh') })
|
||||
|
||||
runLauncherHook([hookSuccess, hookFailing], 1, 2, 3, 4, 5, 6)
|
||||
expect(hookSuccess).toBeCalledTimes(1)
|
||||
|
|
@ -150,7 +156,7 @@ test('runLauncherHook handles async functions', async () => {
|
|||
})
|
||||
|
||||
test('runLauncherHook handles a single function', () => {
|
||||
const hookSuccess = jest.fn()
|
||||
const hookSuccess = vi.fn()
|
||||
|
||||
runLauncherHook(hookSuccess, 1, 2, 3, 4, 5, 6)
|
||||
expect(hookSuccess).toBeCalledTimes(1)
|
||||
|
|
@ -158,8 +164,8 @@ test('runLauncherHook handles a single function', () => {
|
|||
})
|
||||
|
||||
test('runOnCompleteHook handles array of functions', () => {
|
||||
const hookSuccess = jest.fn()
|
||||
const secondHook = jest.fn()
|
||||
const hookSuccess = vi.fn()
|
||||
const secondHook = vi.fn()
|
||||
|
||||
runOnCompleteHook([hookSuccess, secondHook], { capabilities: {} }, {}, 0, {} as any)
|
||||
expect(hookSuccess).toBeCalledTimes(1)
|
||||
|
|
@ -175,15 +181,15 @@ test('runOnCompleteHook handles async functions', async () => {
|
|||
})
|
||||
|
||||
test('runOnCompleteHook handles a single function', () => {
|
||||
const hookSuccess = jest.fn()
|
||||
const hookSuccess = vi.fn()
|
||||
|
||||
runOnCompleteHook(hookSuccess, { capabilities: {} }, {}, 0, {} as any)
|
||||
expect(hookSuccess).toBeCalledTimes(1)
|
||||
})
|
||||
|
||||
test('runOnCompleteHook with no failure returns 0', async () => {
|
||||
const hookSuccess = jest.fn()
|
||||
const hookFailing = jest.fn()
|
||||
const hookSuccess = vi.fn()
|
||||
const hookFailing = vi.fn()
|
||||
|
||||
const result = await runOnCompleteHook([hookSuccess, hookFailing], { capabilities: {} }, {}, 0, {} as any)
|
||||
|
||||
|
|
@ -193,8 +199,8 @@ test('runOnCompleteHook with no failure returns 0', async () => {
|
|||
})
|
||||
|
||||
test('runOnCompleteHook with failure returns 1', async () => {
|
||||
const hookSuccess = jest.fn()
|
||||
const hookFailing = jest.fn().mockImplementation(() => { throw new Error('buhh') })
|
||||
const hookSuccess = vi.fn()
|
||||
const hookFailing = vi.fn().mockImplementation(() => { throw new Error('buhh') })
|
||||
|
||||
const result = await runOnCompleteHook([hookSuccess, hookFailing], { capabilities: {} }, {}, 0, {} as any)
|
||||
|
||||
|
|
@ -204,8 +210,8 @@ test('runOnCompleteHook with failure returns 1', async () => {
|
|||
})
|
||||
|
||||
test('runOnCompleteHook fails with SevereServiceError', async () => {
|
||||
const hookSuccess = jest.fn()
|
||||
const hookFailing = jest.fn().mockImplementation(() => { throw new SevereServiceError('buhh') })
|
||||
const hookSuccess = vi.fn()
|
||||
const hookFailing = vi.fn().mockImplementation(() => { throw new SevereServiceError('buhh') })
|
||||
|
||||
const result = await runOnCompleteHook([hookSuccess, hookFailing], { capabilities: {} }, {}, 0, {} as any)
|
||||
.catch(() => 'some error')
|
||||
|
|
@ -255,30 +261,31 @@ describe('findInConfig', () => {
|
|||
|
||||
describe('renderConfigurationFile', () => {
|
||||
it('should write file', async () => {
|
||||
// @ts-ignore mock feature
|
||||
jest.spyOn(ejs, 'renderFile').mockImplementation((a, b, c) => c(null, true))
|
||||
vi.mocked(ejs.renderFile).mockImplementation((a, b, c: any) => c(null, true))
|
||||
|
||||
await renderConfigurationFile({ foo: 'bar' } as any)
|
||||
|
||||
expect(ejs.renderFile).toHaveBeenCalled()
|
||||
expect(fs.promises.writeFile).toHaveBeenCalled()
|
||||
expect((fs.promises.writeFile as jest.Mock).mock.calls[0][0].endsWith('wdio.conf.js')).toBe(true)
|
||||
expect((vi.mocked(fs.promises.writeFile).mock.calls[0][0] as string)
|
||||
.endsWith('wdio.conf.js')).toBe(true)
|
||||
})
|
||||
|
||||
it('should write TS file', async () => {
|
||||
// @ts-ignore mock feature
|
||||
jest.spyOn(ejs, 'renderFile').mockImplementation((a, b, c) => c(null, true))
|
||||
vi.mocked(ejs.renderFile).mockImplementation((a, b, c) => c(null, true))
|
||||
|
||||
await renderConfigurationFile({ isUsingTypeScript: true } as any)
|
||||
|
||||
expect(ejs.renderFile).toHaveBeenCalled()
|
||||
expect(fs.promises.writeFile).toHaveBeenCalled()
|
||||
expect((fs.promises.writeFile as jest.Mock).mock.calls[0][0].endsWith('wdio.conf.ts')).toBe(true)
|
||||
expect((vi.mocked(fs.promises.writeFile).mock.calls[0][0] as string)
|
||||
.endsWith('wdio.conf.ts')).toBe(true)
|
||||
})
|
||||
|
||||
it('should throw error', async () => {
|
||||
// @ts-ignore mock feature
|
||||
jest.spyOn(ejs, 'renderFile').mockImplementationOnce((a, b, c) => c('test error', null))
|
||||
vi.mocked(ejs.renderFile).mockImplementationOnce((a, b, c) => c('test error', null))
|
||||
|
||||
try {
|
||||
await renderConfigurationFile({ foo: 'bar' } as any)
|
||||
|
|
@ -340,8 +347,9 @@ describe('addServiceDeps', () => {
|
|||
})
|
||||
|
||||
it('should not add appium if globally installed', () => {
|
||||
// @ts-ignore mock feature
|
||||
childProcess.execSyncRes = '1.13.0'
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-import-assign, @typescript-eslint/no-unused-vars
|
||||
execSyncRes = '1.13.0'
|
||||
const packages: any = []
|
||||
addServiceDeps([{ package: '@wdio/appium-service', short: 'appium' }], packages)
|
||||
expect(packages).toEqual([])
|
||||
|
|
@ -370,7 +378,7 @@ describe('addServiceDeps', () => {
|
|||
})
|
||||
|
||||
afterEach(() => {
|
||||
(global.console.log as jest.Mock).mockClear()
|
||||
vi.mocked(global.console.log).mockClear()
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -404,7 +412,8 @@ describe('getCapabilities', () => {
|
|||
})
|
||||
|
||||
it('should return driver with capabilities for ios', () => {
|
||||
expect(getCapabilities({ option: 'foo.app', deviceName: 'fooName', udid: 'num', platformVersion: 'fooNum' } as any)).toMatchSnapshot()
|
||||
expect(getCapabilities({ option: 'foo.app', deviceName: 'fooName', udid: 'num', platformVersion: 'fooNum' } as any))
|
||||
.toMatchSnapshot()
|
||||
expect(getCapabilities({ option: 'ios' } as any)).toMatchSnapshot()
|
||||
})
|
||||
|
||||
|
|
@ -413,7 +422,7 @@ describe('getCapabilities', () => {
|
|||
})
|
||||
|
||||
it('should throw config not found error', () => {
|
||||
const addConfigFileMock = jest.spyOn(ConfigParser.prototype, 'addConfigFile')
|
||||
const addConfigFileMock = vi.spyOn(ConfigParser.prototype, 'addConfigFile')
|
||||
addConfigFileMock.mockImplementationOnce(() => {
|
||||
const error: any = new Error('ups')
|
||||
error.code = 'MODULE_NOT_FOUND'
|
||||
|
|
@ -433,15 +442,15 @@ describe('getCapabilities', () => {
|
|||
|
||||
it('should through capability not found', () => {
|
||||
const cap = { browserName: 'chrome' }
|
||||
const getCapabilitiesMock = jest.spyOn(ConfigParser.prototype, 'getCapabilities')
|
||||
const getCapabilitiesMock = vi.spyOn(ConfigParser.prototype, 'getCapabilities')
|
||||
getCapabilitiesMock.mockReturnValue([cap, cap, cap, cap, cap])
|
||||
expect(() => getCapabilities({ option: '/path/to/config.js', capabilities: 5 } as any))
|
||||
.toThrowErrorMatchingSnapshot()
|
||||
})
|
||||
|
||||
it('should get capability from wdio.conf.js', () => {
|
||||
const autoCompileMock = jest.spyOn(ConfigParser.prototype, 'autoCompile')
|
||||
const getCapabilitiesMock = jest.spyOn(ConfigParser.prototype, 'getCapabilities')
|
||||
const autoCompileMock = vi.spyOn(ConfigParser.prototype, 'autoCompile')
|
||||
const getCapabilitiesMock = vi.spyOn(ConfigParser.prototype, 'getCapabilities')
|
||||
getCapabilitiesMock.mockReturnValue([
|
||||
{ browserName: 'chrome' },
|
||||
{
|
||||
|
|
@ -462,9 +471,9 @@ describe('getCapabilities', () => {
|
|||
})
|
||||
|
||||
test('hasFile', () => {
|
||||
(fs.existsSync as jest.Mock).mockReturnValue(true)
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true)
|
||||
expect(hasFile('package.json')).toBe(true)
|
||||
; (fs.existsSync as jest.Mock).mockReturnValue(false)
|
||||
vi.mocked(fs.existsSync).mockReturnValue(false)
|
||||
expect(hasFile('xyz')).toBe(false)
|
||||
})
|
||||
|
||||
|
|
@ -475,10 +484,10 @@ test('hasPackage', () => {
|
|||
|
||||
describe('generateTestFiles', () => {
|
||||
it('Mocha with page objects', async () => {
|
||||
readDir.mockReturnValue(Promise.resolve([
|
||||
vi.mocked(readDir).mockResolvedValue([
|
||||
'/foo/bar/loo/page.js.ejs',
|
||||
'/foo/bar/example.e2e.js'
|
||||
]))
|
||||
] as any)
|
||||
const answers = {
|
||||
framework: 'mocha',
|
||||
usePageObjects: true,
|
||||
|
|
@ -490,14 +499,14 @@ describe('generateTestFiles', () => {
|
|||
await generateTestFiles(answers as any)
|
||||
|
||||
expect(readDir).toBeCalledTimes(2)
|
||||
expect(readDir.mock.calls[0][0]).toContain('mocha')
|
||||
expect(readDir.mock.calls[1][0]).toContain('pageobjects')
|
||||
expect(vi.mocked(readDir).mock.calls[0][0]).toContain('mocha')
|
||||
expect(vi.mocked(readDir).mock.calls[1][0]).toContain('pageobjects')
|
||||
|
||||
/**
|
||||
* test readDir callback
|
||||
*/
|
||||
const readDirCb = readDir.mock.calls[0][1][0]
|
||||
const stats = { isDirectory: jest.fn().mockReturnValue(false) }
|
||||
const readDirCb = vi.mocked(readDir).mock.calls[0][1][0] as Function
|
||||
const stats = { isDirectory: vi.fn().mockReturnValue(false) }
|
||||
expect(readDirCb('/foo/bar.lala', stats)).toBe(true)
|
||||
expect(readDirCb('/foo/bar.js.ejs', stats)).toBe(false)
|
||||
expect(readDirCb('/foo/bar.feature', stats)).toBe(false)
|
||||
|
|
@ -518,17 +527,17 @@ describe('generateTestFiles', () => {
|
|||
expect.any(Function)
|
||||
)
|
||||
expect(fs.ensureDirSync).toBeCalledTimes(4)
|
||||
expect((fs.promises.writeFile as jest.Mock).mock.calls[0][0].endsWith('/page/objects/model/page.js'))
|
||||
expect((vi.mocked(fs.promises.writeFile).mock.calls[0][0] as string).endsWith('/page/objects/model/page.js'))
|
||||
.toBe(true)
|
||||
expect((fs.promises.writeFile as jest.Mock).mock.calls[1][0].endsWith('/example.e2e.js'))
|
||||
expect((vi.mocked(fs.promises.writeFile).mock.calls[1][0] as string).endsWith('/example.e2e.js'))
|
||||
.toBe(true)
|
||||
})
|
||||
|
||||
it('jasmine with page objects', async () => {
|
||||
readDir.mockReturnValue(Promise.resolve([
|
||||
vi.mocked(readDir).mockResolvedValue([
|
||||
'/foo/bar/loo/page.js.ejs',
|
||||
'/foo/bar/example.e2e.js'
|
||||
]))
|
||||
] as any)
|
||||
const answers = {
|
||||
framework: 'jasmine',
|
||||
usePageObjects: true,
|
||||
|
|
@ -540,14 +549,14 @@ describe('generateTestFiles', () => {
|
|||
await generateTestFiles(answers as any)
|
||||
|
||||
expect(readDir).toBeCalledTimes(2)
|
||||
expect(readDir.mock.calls[0][0]).toContain('jasmine')
|
||||
expect(readDir.mock.calls[1][0]).toContain('pageobjects')
|
||||
expect(vi.mocked(readDir).mock.calls[0][0]).toContain('jasmine')
|
||||
expect(vi.mocked(readDir).mock.calls[1][0]).toContain('pageobjects')
|
||||
|
||||
/**
|
||||
* test readDir callback
|
||||
*/
|
||||
const readDirCb = readDir.mock.calls[0][1][0]
|
||||
const stats = { isDirectory: jest.fn().mockReturnValue(false) }
|
||||
const readDirCb = vi.mocked(readDir).mock.calls[0][1][0] as Function
|
||||
const stats = { isDirectory: vi.fn().mockReturnValue(false) }
|
||||
expect(readDirCb('/foo/bar.lala', stats)).toBe(true)
|
||||
expect(readDirCb('/foo/bar.js.ejs', stats)).toBe(false)
|
||||
expect(readDirCb('/foo/bar.feature', stats)).toBe(false)
|
||||
|
|
@ -568,15 +577,16 @@ describe('generateTestFiles', () => {
|
|||
expect.any(Function)
|
||||
)
|
||||
expect(fs.ensureDirSync).toBeCalledTimes(4)
|
||||
expect((fs.promises.writeFile as jest.Mock).mock.calls[0][0].endsWith('/page/objects/model/page.js'))
|
||||
expect((vi.mocked(fs.promises.writeFile).mock.calls[0][0] as string)
|
||||
.endsWith('/page/objects/model/page.js'))
|
||||
.toBe(true)
|
||||
expect((fs.promises.writeFile as jest.Mock).mock.calls[1][0].endsWith('/example.e2e.js'))
|
||||
expect((vi.mocked(fs.promises.writeFile).mock.calls[1][0] as string)
|
||||
.endsWith('/example.e2e.js'))
|
||||
.toBe(true)
|
||||
})
|
||||
|
||||
it('Jasmine with page generation and no pageObjects', async () => {
|
||||
readDir.mockReturnValue(Promise.resolve([
|
||||
]))
|
||||
vi.mocked(readDir).mockResolvedValue([] as any)
|
||||
const answers = {
|
||||
specs: './tests/e2e/**/*.js',
|
||||
framework: 'jasmine',
|
||||
|
|
@ -591,7 +601,7 @@ describe('generateTestFiles', () => {
|
|||
})
|
||||
|
||||
it('Cucumber with page generation and no pageObjects', async () => {
|
||||
readDir.mockReturnValue(Promise.resolve([]))
|
||||
vi.mocked(readDir).mockResolvedValue([] as any)
|
||||
const answers = {
|
||||
specs: './tests/e2e/**/*.js',
|
||||
framework: 'cucumber',
|
||||
|
|
@ -606,10 +616,10 @@ describe('generateTestFiles', () => {
|
|||
})
|
||||
|
||||
it('Cucumber without page objects', async () => {
|
||||
readDir.mockReturnValue(Promise.resolve([
|
||||
vi.mocked(readDir).mockResolvedValue([
|
||||
'/foo/bar/loo/step_definition/example.step.js',
|
||||
'/foo/bar/example.feature'
|
||||
]))
|
||||
] as any)
|
||||
const answers = {
|
||||
specs: './tests/e2e/*.js',
|
||||
framework: 'cucumber',
|
||||
|
|
@ -620,7 +630,7 @@ describe('generateTestFiles', () => {
|
|||
await generateTestFiles(answers as any)
|
||||
|
||||
expect(readDir).toBeCalledTimes(1)
|
||||
expect(readDir.mock.calls[0][0]).toContain('cucumber')
|
||||
expect(vi.mocked(readDir).mock.calls[0][0]).toContain('cucumber')
|
||||
expect(ejs.renderFile).toBeCalledTimes(2)
|
||||
expect(ejs.renderFile).toBeCalledWith(
|
||||
'/foo/bar/loo/step_definition/example.step.js',
|
||||
|
|
@ -636,11 +646,11 @@ describe('generateTestFiles', () => {
|
|||
})
|
||||
|
||||
it('Cucumber with page objects and TypeScript', async () => {
|
||||
readDir.mockReturnValue(Promise.resolve([
|
||||
vi.mocked(readDir).mockResolvedValue([
|
||||
'/foo/bar/loo/page.js.ejs',
|
||||
'/foo/bar/loo/step_definition/example.step.js',
|
||||
'/foo/bar/example.feature'
|
||||
]))
|
||||
] as any)
|
||||
const answers = {
|
||||
framework: 'cucumber',
|
||||
usePageObjects: true,
|
||||
|
|
@ -652,7 +662,7 @@ describe('generateTestFiles', () => {
|
|||
await generateTestFiles(answers as any)
|
||||
|
||||
expect(readDir).toBeCalledTimes(2)
|
||||
expect(readDir.mock.calls[0][0]).toContain('cucumber')
|
||||
expect(vi.mocked(readDir).mock.calls[0][0]).toContain('cucumber')
|
||||
expect(ejs.renderFile).toBeCalledTimes(6)
|
||||
expect(ejs.renderFile).toBeCalledWith(
|
||||
'/foo/bar/loo/step_definition/example.step.js',
|
||||
|
|
@ -665,9 +675,9 @@ describe('generateTestFiles', () => {
|
|||
expect.any(Function)
|
||||
)
|
||||
expect(fs.ensureDirSync).toBeCalledTimes(6)
|
||||
expect((fs.promises.writeFile as jest.Mock).mock.calls[0][0].endsWith('/some/page/objects/page.ts'))
|
||||
expect((vi.mocked(fs.promises.writeFile).mock.calls[0][0] as string).endsWith('/some/page/objects/page.ts'))
|
||||
.toBe(true)
|
||||
expect((fs.promises.writeFile as jest.Mock).mock.calls[2][0].endsWith('/example.feature'))
|
||||
expect((vi.mocked(fs.promises.writeFile).mock.calls[2][0] as string).endsWith('/example.feature'))
|
||||
.toBe(true)
|
||||
})
|
||||
})
|
||||
|
|
@ -751,9 +761,9 @@ test('getDefaultFiles', () => {
|
|||
})
|
||||
|
||||
afterEach(() => {
|
||||
(console.log as jest.Mock).mockRestore()
|
||||
readDir.mockClear()
|
||||
; (fs.promises.writeFile as jest.Mock).mockClear()
|
||||
; (fs.ensureDirSync as jest.Mock).mockClear()
|
||||
; (ejs.renderFile as jest.Mock).mockClear()
|
||||
vi.mocked(console.log).mockRestore()
|
||||
vi.mocked(readDir).mockClear()
|
||||
vi.mocked(fs.promises.writeFile).mockClear()
|
||||
vi.mocked(fs.ensureDirSync).mockClear()
|
||||
vi.mocked(ejs.renderFile).mockClear()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { vi, describe, it, expect, afterEach } from 'vitest'
|
||||
import path from 'node:path'
|
||||
import chokidar from 'chokidar'
|
||||
import EventEmitter from 'node:events'
|
||||
|
|
@ -6,8 +7,12 @@ import type { Workers } from '@wdio/types'
|
|||
import { RunCommandArguments } from '../src/types'
|
||||
import Watcher from '../src/watcher'
|
||||
|
||||
jest.mock('../src/launcher', () => {
|
||||
const { ConfigParser } = require('@wdio/config')
|
||||
vi.mock('chokidar')
|
||||
vi.mock('@wdio/logger', () => import(path.join(process.cwd(), '__mocks__', '@wdio/logger')))
|
||||
vi.mock('@wdio/config', () => import(path.join(process.cwd(), '__mocks__', '@wdio/config')))
|
||||
vi.mock('@wdio/utils', () => import(path.join(process.cwd(), '__mocks__', '@wdio/utils')))
|
||||
vi.mock('../src/launcher', async () => {
|
||||
const { ConfigParser } = await import('@wdio/config')
|
||||
|
||||
interface LauncherMockRunCommandArguments extends Omit<RunCommandArguments, 'configPath'> {
|
||||
isMultiremote?: boolean;
|
||||
|
|
@ -28,12 +33,12 @@ jest.mock('../src/launcher', () => {
|
|||
this.isMultiremote = args.isMultiremote || false
|
||||
this.runner = {}
|
||||
this.interface = {
|
||||
emit: jest.fn(),
|
||||
setup: jest.fn()
|
||||
emit: vi.fn(),
|
||||
setup: vi.fn()
|
||||
}
|
||||
}
|
||||
}
|
||||
return LauncherMock
|
||||
return { default: LauncherMock }
|
||||
})
|
||||
|
||||
interface WorkerMockRunPayload extends Partial<Workers.WorkerRunPayload> {
|
||||
|
|
@ -49,7 +54,7 @@ class WorkerMock extends EventEmitter implements Workers.Worker {
|
|||
capabilities: WebDriver.DesiredCapabilities
|
||||
sessionId: string
|
||||
isBusy: boolean
|
||||
postMessage = jest.fn()
|
||||
postMessage = vi.fn()
|
||||
|
||||
constructor ({ cid, specs, sessionId, isBusy = false }: WorkerMockRunPayload) {
|
||||
super()
|
||||
|
|
@ -59,7 +64,7 @@ class WorkerMock extends EventEmitter implements Workers.Worker {
|
|||
this.capabilities = this.caps
|
||||
this.sessionId = sessionId || `${Math.random()}`
|
||||
this.isBusy = isBusy
|
||||
this.on = jest.fn()
|
||||
this.on = vi.fn()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,12 +90,12 @@ describe('watcher', () => {
|
|||
const wdioConf = path.join(__dirname, '__fixtures__', 'wdio.conf')
|
||||
const watcher = new Watcher(wdioConf, {})
|
||||
watcher['_launcher'] = {
|
||||
run: jest.fn(),
|
||||
run: vi.fn(),
|
||||
interface: {
|
||||
finalise: jest.fn()
|
||||
finalise: vi.fn()
|
||||
},
|
||||
configParser: {
|
||||
getConfig: jest.fn().mockReturnValue({ filesToWatch: [] })
|
||||
getConfig: vi.fn().mockReturnValue({ filesToWatch: [] })
|
||||
},
|
||||
runner: {
|
||||
workerPool: {
|
||||
|
|
@ -107,12 +112,12 @@ describe('watcher', () => {
|
|||
const wdioConf = path.join(__dirname, '__fixtures__', 'wdio.conf')
|
||||
const watcher = new Watcher(wdioConf, {})
|
||||
watcher['_launcher'] = {
|
||||
run: jest.fn(),
|
||||
run: vi.fn(),
|
||||
interface: {
|
||||
finalise: jest.fn()
|
||||
finalise: vi.fn()
|
||||
},
|
||||
configParser: {
|
||||
getConfig: jest.fn().mockReturnValue({ filesToWatch: [] })
|
||||
getConfig: vi.fn().mockReturnValue({ filesToWatch: [] })
|
||||
},
|
||||
runner: {
|
||||
workerPool: {
|
||||
|
|
@ -129,12 +134,12 @@ describe('watcher', () => {
|
|||
const wdioConf = path.join(__dirname, '__fixtures__', 'wdio.conf')
|
||||
const watcher = new Watcher(wdioConf, {})
|
||||
watcher['_launcher'] = {
|
||||
run: jest.fn(),
|
||||
run: vi.fn(),
|
||||
interface: {
|
||||
finalise: jest.fn()
|
||||
finalise: vi.fn()
|
||||
},
|
||||
configParser: {
|
||||
getConfig: jest.fn().mockReturnValue({ filesToWatch: ['/foo/bar'] })
|
||||
getConfig: vi.fn().mockReturnValue({ filesToWatch: ['/foo/bar'] })
|
||||
},
|
||||
runner: {
|
||||
workerPool: {
|
||||
|
|
@ -146,7 +151,7 @@ describe('watcher', () => {
|
|||
|
||||
expect(chokidar.watch).toHaveBeenCalledTimes(2)
|
||||
|
||||
const worker = watcher['_launcher'].runner.workerPool['0-0']
|
||||
const worker = watcher['_launcher'].runner!.workerPool['0-0']
|
||||
expect(worker.on).toBeCalledTimes(1)
|
||||
|
||||
const eventHandler = worker.on.mock.calls[0][1]
|
||||
|
|
@ -163,12 +168,12 @@ describe('watcher', () => {
|
|||
const wdioConf = path.join(__dirname, '__fixtures__', 'wdio.conf')
|
||||
const watcher = new Watcher(wdioConf, {})
|
||||
watcher['_launcher'] = {
|
||||
run: jest.fn(),
|
||||
run: vi.fn(),
|
||||
interface: {
|
||||
finalise: jest.fn()
|
||||
finalise: vi.fn()
|
||||
},
|
||||
configParser: {
|
||||
getConfig: jest.fn().mockReturnValue({ filesToWatch: ['/foo/bar'] })
|
||||
getConfig: vi.fn().mockReturnValue({ filesToWatch: ['/foo/bar'] })
|
||||
},
|
||||
runner: {
|
||||
workerPool: {
|
||||
|
|
@ -176,17 +181,17 @@ describe('watcher', () => {
|
|||
}
|
||||
}
|
||||
} as any
|
||||
watcher.run = jest.fn()
|
||||
watcher.run = vi.fn()
|
||||
await watcher.watch()
|
||||
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[0][1]('/some/path.js')
|
||||
vi.mocked(chokidar.on).mock.calls[0][1]('/some/path.js')
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[1][1]('/some/other/path.js')
|
||||
vi.mocked(chokidar.on).mock.calls[1][1]('/some/other/path.js')
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[2][1]('/some/another/path.js')
|
||||
vi.mocked(chokidar.on).mock.calls[2][1]('/some/another/path.js')
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[3][1]('/some/another/path.js')
|
||||
vi.mocked(chokidar.on).mock.calls[3][1]('/some/another/path.js')
|
||||
expect(watcher.run).toHaveBeenNthCalledWith(1, { spec: '/some/path.js' })
|
||||
expect(watcher.run).toHaveBeenNthCalledWith(2, { spec: '/some/other/path.js' })
|
||||
expect(watcher.run).toHaveBeenNthCalledWith(3, {})
|
||||
|
|
@ -201,7 +206,7 @@ describe('watcher', () => {
|
|||
'0-1': new WorkerMock({ cid: '0-1', specs: ['/foo/bar2.js'], isBusy: true }),
|
||||
'1-0': new WorkerMock({ cid: '1-0', specs: ['/bar/foo.js'] })
|
||||
}
|
||||
watcher['_launcher'].runner.workerPool = workerPool
|
||||
watcher['_launcher'].runner!.workerPool = workerPool
|
||||
|
||||
expect(watcher.getWorkers(null, true)).toEqual(workerPool)
|
||||
expect(watcher.getWorkers()).toEqual({
|
||||
|
|
@ -216,14 +221,14 @@ describe('watcher', () => {
|
|||
it('should run workers on existing session', () => {
|
||||
const wdioConf = path.join(__dirname, '__fixtures__', 'wdio.conf')
|
||||
const watcher = new Watcher(wdioConf, {})
|
||||
watcher['_launcher'].runner.workerPool = {
|
||||
watcher['_launcher'].runner!.workerPool = {
|
||||
// @ts-ignore mock feature
|
||||
'0-0': new WorkerMock({ cid: '0-0', specs: ['/foo/bar.js'] }),
|
||||
'0-1': new WorkerMock({ cid: '0-1', specs: ['/foo/bar2.js'], isBusy: true }),
|
||||
// @ts-ignore mock feature
|
||||
'1-0': new WorkerMock({ cid: '1-0', specs: ['/bar/foo.js'] })
|
||||
}
|
||||
watcher['_launcher'].interface.emit = jest.fn()
|
||||
watcher['_launcher'].interface.emit = vi.fn()
|
||||
watcher.run({ spec: '/foo/bar.js' } as any)
|
||||
expect(watcher['_launcher'].interface.emit).toHaveBeenCalledWith('job:start', {
|
||||
cid: '0-0',
|
||||
|
|
@ -231,7 +236,7 @@ describe('watcher', () => {
|
|||
specs: ['/foo/bar.js']
|
||||
})
|
||||
|
||||
const { postMessage, sessionId } = watcher['_launcher'].runner.workerPool['0-0']
|
||||
const { postMessage, sessionId } = watcher['_launcher'].runner!.workerPool['0-0']
|
||||
expect(postMessage).toHaveBeenCalledWith('run', { sessionId, spec: '/foo/bar.js' })
|
||||
expect(watcher['_launcher'].interface.totalWorkerCnt).toBe(1)
|
||||
})
|
||||
|
|
@ -239,14 +244,14 @@ describe('watcher', () => {
|
|||
it('should not clean if no watcher is running', () => {
|
||||
const wdioConf = path.join(__dirname, '__fixtures__', 'wdio.conf')
|
||||
const watcher = new Watcher(wdioConf, {})
|
||||
watcher['_launcher'].runner.workerPool = {
|
||||
watcher['_launcher'].runner!.workerPool = {
|
||||
// @ts-ignore mock feature
|
||||
'0-0': new WorkerMock({ cid: '0-0', specs: ['/foo/bar.js'] }),
|
||||
'0-1': new WorkerMock({ cid: '0-1', specs: ['/foo/bar2.js'], isBusy: true }),
|
||||
// @ts-ignore mock feature
|
||||
'1-0': new WorkerMock({ cid: '1-0', specs: ['/bar/foo.js'] })
|
||||
}
|
||||
watcher['_launcher'].interface.emit = jest.fn()
|
||||
watcher['_launcher'].interface.emit = vi.fn()
|
||||
watcher.run({ spec: '/foo/bar2.js' } as any)
|
||||
expect(watcher['_launcher'].interface.emit).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
|
@ -255,8 +260,8 @@ describe('watcher', () => {
|
|||
const wdioConf = path.join(__dirname, '__fixtures__', 'wdio.conf')
|
||||
const watcher = new Watcher(wdioConf, {})
|
||||
watcher['_launcher'].interface.totalWorkerCnt = 1
|
||||
watcher.cleanUp = jest.fn()
|
||||
watcher['_launcher'].runner.workerPool = {
|
||||
watcher.cleanUp = vi.fn()
|
||||
watcher['_launcher'].runner!.workerPool = {
|
||||
// @ts-ignore mock feature
|
||||
'0-0': new WorkerMock({ cid: '0-0', specs: ['/foo/bar.js'] }),
|
||||
'0-1': new WorkerMock({ cid: '0-1', specs: ['/foo/bar2.js'], isBusy: true }),
|
||||
|
|
@ -267,7 +272,7 @@ describe('watcher', () => {
|
|||
|
||||
expect(watcher['_launcher'].interface.totalWorkerCnt).toBe(2)
|
||||
|
||||
const worker00 = watcher['_launcher'].runner.workerPool['0-0']
|
||||
const worker00 = watcher['_launcher'].runner!.workerPool['0-0']
|
||||
expect(worker00.postMessage).toHaveBeenCalledWith(
|
||||
'run',
|
||||
{ sessionId: worker00.sessionId })
|
||||
|
|
@ -276,7 +281,7 @@ describe('watcher', () => {
|
|||
caps: { browserName: 'chrome' },
|
||||
specs: ['/foo/bar.js'] })
|
||||
|
||||
const worker10 = watcher['_launcher'].runner.workerPool['0-0']
|
||||
const worker10 = watcher['_launcher'].runner!.workerPool['0-0']
|
||||
expect(worker10.postMessage).toHaveBeenCalledWith(
|
||||
'run',
|
||||
{ sessionId: worker10.sessionId })
|
||||
|
|
@ -294,13 +299,13 @@ describe('watcher', () => {
|
|||
const watcher = new Watcher(wdioConf, {})
|
||||
watcher['_launcher'] = {
|
||||
__args: { spec },
|
||||
run: jest.fn(),
|
||||
run: vi.fn(),
|
||||
interface: {
|
||||
emit: jest.fn(),
|
||||
finalise: jest.fn()
|
||||
emit: vi.fn(),
|
||||
finalise: vi.fn()
|
||||
},
|
||||
configParser: {
|
||||
getConfig: jest.fn().mockReturnValue({ filesToWatch })
|
||||
getConfig: vi.fn().mockReturnValue({ filesToWatch })
|
||||
},
|
||||
runner: {
|
||||
workerPool: {
|
||||
|
|
@ -309,31 +314,31 @@ describe('watcher', () => {
|
|||
}
|
||||
}
|
||||
} as any
|
||||
const runSpy = jest.spyOn(watcher, 'run')
|
||||
const runSpy = vi.spyOn(watcher, 'run')
|
||||
const emitSpy = watcher['_launcher'].interface.emit
|
||||
watcher.cleanUp = jest.fn()
|
||||
watcher.cleanUp = vi.fn()
|
||||
await watcher.watch()
|
||||
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[0][1](spec[0])
|
||||
vi.mocked(chokidar.on).mock.calls[0][1](spec[0])
|
||||
expect(runSpy).toHaveBeenNthCalledWith(1, { spec: spec[0] })
|
||||
expect(emitSpy).toHaveBeenCalledTimes(1) // Only one Worker called
|
||||
|
||||
;(emitSpy as jest.Mock).mockClear()
|
||||
vi.mocked(emitSpy).mockClear()
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[1][1](someOtherExcludedPath)
|
||||
vi.mocked(chokidar.on).mock.calls[1][1](someOtherExcludedPath)
|
||||
expect(runSpy).toHaveBeenNthCalledWith(2, { spec: someOtherExcludedPath })
|
||||
expect(emitSpy).not.toHaveBeenCalled() // No Workers called
|
||||
|
||||
;(emitSpy as jest.Mock).mockClear()
|
||||
vi.mocked(emitSpy).mockClear()
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[2][1](filesToWatch[0])
|
||||
vi.mocked(chokidar.on).mock.calls[2][1](filesToWatch[0])
|
||||
expect(runSpy).toHaveBeenNthCalledWith(3, {})
|
||||
expect(emitSpy).toHaveBeenCalledTimes(2) // Both Workers called
|
||||
|
||||
;(emitSpy as jest.Mock).mockClear()
|
||||
vi.mocked(emitSpy).mockClear()
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[3][1](filesToWatch[0])
|
||||
vi.mocked(chokidar.on).mock.calls[3][1](filesToWatch[0])
|
||||
expect(runSpy).toHaveBeenNthCalledWith(4, {})
|
||||
expect(emitSpy).toHaveBeenCalledTimes(2) // Both Workers called
|
||||
})
|
||||
|
|
@ -347,52 +352,52 @@ describe('watcher', () => {
|
|||
// @ts-ignore
|
||||
watcher['_launcher'] = {
|
||||
__args: { spec },
|
||||
run: jest.fn(),
|
||||
run: vi.fn(),
|
||||
interface: {
|
||||
emit: jest.fn(),
|
||||
finalise: jest.fn()
|
||||
emit: vi.fn(),
|
||||
finalise: vi.fn()
|
||||
},
|
||||
configParser: {
|
||||
getConfig: jest.fn().mockReturnValue({ filesToWatch })
|
||||
getConfig: vi.fn().mockReturnValue({ filesToWatch })
|
||||
},
|
||||
runner: {
|
||||
workerPool: {
|
||||
'0-0': new WorkerMock({ cid: '0-0', specs: [spec[0]] }),
|
||||
'0-1': new WorkerMock({ cid: '0-1', specs: [spec[1]] })
|
||||
'0-0': new WorkerMock({ cid: '0-0', specs: [spec[0] as any] }),
|
||||
'0-1': new WorkerMock({ cid: '0-1', specs: [spec[1] as any] })
|
||||
}
|
||||
}
|
||||
} as any
|
||||
const runSpy = jest.spyOn(watcher, 'run')
|
||||
const runSpy = vi.spyOn(watcher, 'run')
|
||||
const emitSpy = watcher['_launcher'].interface.emit
|
||||
watcher.cleanUp = jest.fn()
|
||||
watcher.cleanUp = vi.fn()
|
||||
await watcher.watch()
|
||||
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[0][1](spec[0])
|
||||
vi.mocked(chokidar.on).mock.calls[0][1](spec[0])
|
||||
expect(runSpy).toHaveBeenNthCalledWith(1, { spec: spec[0] })
|
||||
expect(emitSpy).toHaveBeenCalledTimes(1) // Only one Worker called
|
||||
|
||||
;(emitSpy as jest.Mock).mockClear()
|
||||
vi.mocked(emitSpy).mockClear()
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[1][1](someOtherExcludedPath)
|
||||
vi.mocked(chokidar.on).mock.calls[1][1](someOtherExcludedPath)
|
||||
expect(runSpy).toHaveBeenNthCalledWith(2, { spec: someOtherExcludedPath })
|
||||
expect(emitSpy).not.toHaveBeenCalled() // No Workers called
|
||||
|
||||
;(emitSpy as jest.Mock).mockClear()
|
||||
vi.mocked(emitSpy).mockClear()
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[2][1](filesToWatch[0])
|
||||
vi.mocked(chokidar.on).mock.calls[2][1](filesToWatch[0])
|
||||
expect(runSpy).toHaveBeenNthCalledWith(3, {})
|
||||
expect(emitSpy).toHaveBeenCalledTimes(2) // Both Workers called
|
||||
|
||||
;(emitSpy as jest.Mock).mockClear()
|
||||
vi.mocked(emitSpy).mockClear()
|
||||
// @ts-ignore mock feature
|
||||
;(chokidar.on as jest.Mock).mock.calls[3][1](filesToWatch[0])
|
||||
vi.mocked(chokidar.on).mock.calls[3][1](filesToWatch[0])
|
||||
expect(runSpy).toHaveBeenNthCalledWith(4, {})
|
||||
expect(emitSpy).toHaveBeenCalledTimes(2) // Both Workers called
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
(chokidar.watch as jest.Mock).mockClear()
|
||||
vi.mocked(chokidar.watch).mockClear()
|
||||
// @ts-ignore mock feature
|
||||
chokidar.on.mockClear()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ export default defineConfig({
|
|||
'dist', '.idea', '.git', '.cache',
|
||||
'**/node_modules/**',
|
||||
'packages/eslint-plugin-wdio/**/*',
|
||||
'packages/wdio-cli/**/*.test.ts',
|
||||
'packages/webdriverio/**/*.test.ts',
|
||||
'packages/wdio-jasmine-framework/**/*.test.ts'
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in a new issue