Code Mage LogoCode Mage
TutorialsWebdriverIOInstallation & Configuration

๐Ÿค– WebdriverIO ยท Chapter 2 of 8

Installation & Configuration

Install WebdriverIO using the CLI wizard and write your first passing test

All chapters (8)

WDIO has a setup wizard that handles most of the configuration. This chapter walks you through it and explains every choice.

Prerequisites

Node.js 18 or later:

node --version  # v18.0.0 or higher

Running the Setup Wizard

Create a project directory and run the wizard:

mkdir wdio-saucedemo
cd wdio-saucedemo
npm init -y
npm init wdio@latest .

The wizard asks several questions. Here are the recommended choices for this tutorial:

What type of testing would you like to do?
  โ†’ E2E Testing - of Web or Mobile Applications

Where is your automation backend located?
  โ†’ On my local machine

Which environment you would like to automate?
  โ†’ Web - web applications in the browser

With which browser should we start?
  โ†’ Chrome

Which framework do you want to use?
  โ†’ Mocha

Do you want to use a compiler?
  โ†’ TypeScript (recommended)

Do you want WebdriverIO to autogenerate some test files?
  โ†’ Yes

Would you like to add a service to your project?
  โ†’ chromedriver (select this to avoid manual driver setup)

What is the base url?
  โ†’ https://www.saucedemo.com

Do you want me to run npm install for you?
  โ†’ Yes

What Gets Created

After setup, your project looks like:

wdio-saucedemo/
  test/
    specs/
      example.e2e.ts   โ† example test file
  wdio.conf.ts         โ† main configuration
  tsconfig.json        โ† TypeScript config
  package.json

Understanding wdio.conf.ts

The config file controls everything. Key sections:

export const config: Options.Testrunner = {
  // Base URL โ€” used with browser.url('/')
  baseUrl: 'https://www.saucedemo.com',

  // Test files to run
  specs: ['./test/specs/**/*.ts'],

  // How many browsers to run in parallel
  maxInstances: 5,

  // Browser capabilities
  capabilities: [{
    browserName: 'chrome',
    'goog:chromeOptions': {
      args: ['--headless']  // remove this for headed mode
    }
  }],

  // Test framework
  framework: 'mocha',
  mochaOpts: {
    timeout: 60000  // 60s timeout per test
  },

  // Automatic waiting
  waitforTimeout: 5000,  // how long to wait for elements

  // Retry failed tests
  bail: 0,  // 0 = don't stop on failure

  // Reporter
  reporters: ['spec'],
}

Your First Test

Replace the content of test/specs/example.e2e.ts:

describe('SauceDemo Login', () => {
  it('should login with valid credentials', async () => {
    await browser.url('/')

    await $('#user-name').setValue('standard_user')
    await $('#password').setValue('secret_sauce')
    await $('#login-button').click()

    await expect(browser).toHaveUrl(expect.stringContaining('/inventory'))
    await expect($('.inventory_list')).toBeDisplayed()
  })

  it('should show error for invalid credentials', async () => {
    await browser.url('/')

    await $('#user-name').setValue('wrong_user')
    await $('#password').setValue('wrong_pass')
    await $('#login-button').click()

    const errorMessage = await $('[data-test="error"]')
    await expect(errorMessage).toBeDisplayed()
    await expect(errorMessage).toHaveText(
      expect.stringContaining('Username and password do not match')
    )
  })
})

Run the tests:

npx wdio run wdio.conf.ts

You'll see output like:

[chrome 120.0.0.0 / linux] Running: 2 tests
โœ“ SauceDemo Login should login with valid credentials (1.2s)
โœ“ SauceDemo Login should show error for invalid credentials (0.9s)

2 passing (2.3s)

Headed vs Headless Mode

During development, run headed (with visible browser) for easier debugging. In CI, run headless.

Headed (remove --headless from capabilities):

capabilities: [{
  browserName: 'chrome',
  // no args โ€” browser opens visibly
}],

Headless:

capabilities: [{
  browserName: 'chrome',
  'goog:chromeOptions': {
    args: ['--headless', '--disable-gpu']
  }
}],

You can also pass this via CLI without changing the config:

npx wdio run wdio.conf.ts --headless

Running a Single Spec

npx wdio run wdio.conf.ts --spec test/specs/login.e2e.ts

Setting Up Multiple Browsers

To run in Chrome and Firefox simultaneously:

capabilities: [
  { browserName: 'chrome' },
  { browserName: 'firefox' },
],
maxInstances: 2,

Install geckodriver: npm install --save-dev wdio-geckodriver-service

TypeScript Path Aliases

For cleaner imports, add path aliases to tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@pages/*": ["test/pages/*"],
      "@data/*": ["test/data/*"]
    }
  }
}

And in wdio.conf.ts:

import { compilerOptions } from './tsconfig.json'
import { pathsToModuleNameMapper } from 'ts-jest'

// Add to config:
mochaOpts: {
  require: ['ts-node/register'],
},

Debugging Tests

Add browser.debug() to pause execution and open a REPL:

it('should debug', async () => {
  await browser.url('/')
  await browser.debug()  // pauses here, opens interactive REPL
  // type browser commands in the terminal
})

Or use VS Code's debugger by adding a .vscode/launch.json:

{
  "type": "node",
  "request": "launch",
  "name": "WDIO Debug",
  "program": "${workspaceFolder}/node_modules/.bin/wdio",
  "args": ["run", "wdio.conf.ts"],
  "console": "integratedTerminal"
}

Common Setup Issues

chromedriver not found: Install explicitly: npm install --save-dev chromedriver

Cannot find module 'ts-node': npm install --save-dev ts-node

Tests timeout immediately: Check waitforTimeout in wdio.conf.ts. Increase to 10000 for slow connections.

browser is not defined: You're running the file directly with node instead of npx wdio run. Always use the WDIO runner.

Next chapter: selectors, commands, and writing real test scenarios.