TypeScript Setup

You can write tests using TypeScript to get autocompletion and type safety.

You will need typescript and ts-node installed as devDependencies. WebdriverIO will automatically detect if these dependencies are installed and will compile your config and tests for you.

$ npm install typescript ts-node --save-dev

The minimum TypeScript version is 3.8.3.

Framework Setup#

And your tsconfig.json needs the following:

tsconfig.json
{
"compilerOptions": {
"types": ["node", "webdriverio/sync"]
}
}

Please avoid importing webdriverio or @wdio/sync explicitly. WebdriverIO and WebDriver types are accessible from anywhere once added to types in tsconfig.json.

Framework types#

Depending on the framework you use, you will need to add the types for that framework to your tsconfig.json types property, as well as install its type definitions. This is especially important if you want to have type support for the built-in assertion library expect-webdriverio.

For instance, if you decide to use the Mocha framework, you need to install @types/mocha and add it like this to have all types globally available:

tsconfig.json
{
"compilerOptions": {
"types": ["node", "webdriverio/sync", "@wdio/mocha-framework"]
},
"include": [
"./test/**/*.ts"
]
}

Services#

If you use services that add commands to the browser scope you also need to include these into your tsconfig.json. For example if you use the @wdio/devtools-service ensure that you add it to the types as well, e.g.:

tsconfig.json
{
"compilerOptions": {
"types": [
"node",
"webdriverio/sync",
"@wdio/mocha-framework",
"@wdio/devtools-service"
]
},
"include": [
"./test/**/*.ts"
]
}

Adding services and reporters to your TypeScript config also strengthen the type safety of your WebdriverIO config file.

Adding custom commands#

With TypeScript, it's easy to extend WebdriverIO interfaces. Add types to your custom commands like this:

  1. Create a type definition file (e.g., ./src/types/wdio.d.ts)
  2. Make sure to include path in the tsconfig.json
tsconfig.json
{
"compilerOptions": { ... },
"include": [
"./test/**/*.ts",
"./src/**/*.ts"
]
}
  1. Add definitions for your commands according to your execution mode.
declare global {
namespace WebdriverIO {
interface Browser {
browserCustomCommand: (arg: any) => void
}
interface MultiRemoteBrowser {
browserCustomCommand: (arg: any) => void
}
interface Element {
elementCustomCommand: (arg: any) => number
}
}
}

Tips and Hints#

tsconfig.json example#

{
"compilerOptions": {
"outDir": "./.tsbuild/",
"sourceMap": false,
"target": "es2019",
"module": "commonjs",
"removeComments": true,
"noImplicitAny": true,
"strictPropertyInitialization": true,
"strictNullChecks": true,
"types": [
"node",
"webdriverio/sync",
"@wdio/mocha-framework"
],
},
"include": [
"./test/**/*.ts"
]
}

Compile & Lint#

To be entirely safe, you may consider following the best practices: compile your code with TypeScript compiler (run tsc or npx tsc) and have eslint running on pre-commit hook.