Running WebdriverIO Tests on CircleCI
Continuous integration (CI) helps teams catch issues early, and CircleCI is a popular choice for automating tests in the cloud. In this article, we’ll demonstrate how to run a WebdriverIO test suite on CircleCI using Firefox in headless mode. We’ll cover the necessary configuration files and explain the test code.
Prerequisites
Before you begin, make sure you have:
- A CircleCI account.
- A repository (e.g., on GitHub) where your tests are stored.
- Node.js and npm are installed locally for development.
- Basic knowledge of WebdriverIO and Mocha (or your preferred test framework).
WebdriverIO Configuration
Below is an example of a wdio.conf.js
file. In this configuration, we set up Firefox in headless mode with a specific window size. We also define the test files to execute (located in ./test/specs/**/*.js
) and configure Mocha as the test framework.
exports.config = {
runner: 'local',
specs: [
'./test/specs/**/*.js'
],
exclude: [],
maxInstances: 10,
capabilities: [{
browserName: 'firefox', // Use Firefox
'moz:firefoxOptions': { // Firefox-specific options
args: [
'--headless', // Headless mode
'--window-size=1280,800' // Window size
// Add other Firefox-specific arguments as needed
],
binary: '/usr/bin/firefox-esr' // Path to Firefox executable
},
}],
logLevel: 'info',
bail: 0,
waitforTimeout: 10000,
connectionRetryTimeout: 120000,
connectionRetryCount: 3,
framework: 'mocha',
mochaOpts: {
ui: 'bdd',
timeout: 60000
}
};
What This Configuration Does
- Runner and Specs: The tests are run locally using the defined specs pattern.
- Capabilities: Firefox is configured to run in headless mode with a fixed window size. The
binary
path points to Firefox ESR on many Linux distributions. - Timeouts and Logging: Global timeouts and log levels are set to ensure tests do not hang and that the output is informative.
- Framework Settings: Mocha is used as the test framework with a Behavior-Driven Development (BDD) style.
Sample Test Code
Here’s a sample test file that verifies the login functionality on SauceDemo. Two scenarios are covered: one for a valid login and another for an invalid login.
const { expect } = require('@wdio/globals')
describe('SauceDemo Login Page', () => {
it('should allow valid login and display products page', async () => {
await browser.url('https://www.saucedemo.com/');
const loginTitle = await $('div.login_logo');
await expect(loginTitle).toBeDisplayed();
const usernameField = await $('#user-name');
await usernameField.setValue('standard_user');
const passwordField = await $('#password');
await passwordField.setValue('secret_sauce');
const loginButton = await $('#login-button');
await loginButton.click();
const productsTitle = await $('div.product_label');
const firstProduct = await $('.inventory_item');
await expect(firstProduct).toBeDisplayed();
});
it('should show an error for invalid login', async () => {
await browser.url('https://www.saucedemo.com/');
const usernameField = await $('#user-name');
await usernameField.setValue('invalid_user');
const passwordField = await $('#password');
await passwordField.setValue('invalid_password');
const loginButton = await $('#login-button');
await loginButton.click();
const errorMessage = await $('h3[data-test="error"]');
await expect(errorMessage).toBeDisplayed();
});
});
Explanation
- Valid Login Test: The script navigates to SauceDemo, verifies the login page, inputs valid credentials, clicks the login button, and then checks that a product is displayed on the products page.
- Invalid Login Test: It follows a similar pattern, but inputs invalid credentials and verifies that an error message appears.
The CircleCI Configuration
Your CircleCI configuration is defined in a YAML file (.circleci/config.yml
). Here’s your provided configuration:
version: 2.1
jobs:
test:
docker:
- image: pradapjackie/webdriverio-firefox-amd64:latest
steps:
- checkout
- run:
name: install dependency
command: npm i
- run:
name: Run WebdriverIO Tests
command: npm run wdio
workflows:
version: 2
build_and_test:
jobs:
- test
I have created a docker image and pushed to the docker hub with the name pradapjackie/webdriverio-firefox-amd64:latest
to run the test on Circleci. You can try this image running locally too.
Breakdown of the Configuration
Version:
version: 2.1
: This specifies the configuration version of CircleCI. Version 2.1 offers new features like reusable configurations and orbs.
Jobs:
- Job Name (
test
): Thetest
job is defined to run your WebdriverIO tests. - Docker Image:
- The job uses the Docker image
pradapjackie/webdriverio-firefox-amd64:latest
, which is a preconfigured image containing WebdriverIO and Firefox for AMD64 architectures. This image already includes Firefox and any required dependencies, making it easier to run browser tests in a headless environment.
Steps:
- Checkout: This step checks out your repository code.
- Install Dependencies: The command
npm i
installs all necessary Node.js packages defined in yourpackage.json
. - Run Tests: The command
npm run wdio
is executed to start the WebdriverIO test suite. Make sure yourpackage.json
has a script defined forwdio
(for example,"wdio": "wdio run wdio.conf.js"
).
Workflows:
- Workflow Name (
build_and_test
): This defines a workflow that consists of thetest
job. - Jobs in Workflow: The workflow executes the
test
job. Workflows allow you to orchestrate and manage multiple jobs, which is useful if you plan to extend your CI pipeline later.
Once the test is executed you can store the artifacts and am not storing anything on the artifacts in this article.
Conclusion
By following the steps outlined above, you can set up your WebdriverIO test suite to run on CircleCI. This integration helps automate your browser testing pipeline, ensuring that any issues are caught early in your development cycle. With Firefox running in headless mode, your tests can execute efficiently in a CI environment without needing a graphical interface.
I have created a project on GitHub and added the code here.
Also, I have kept the job in public on Circleci in case you guys want to check the implementation here.
Feel free to hit clap if you like the content. Happy Automation Testing :) Cheers. 👏