Contribute
You like WebdriverIO and want to help making it better? Awesome! We are working to make this process as easy and transparent as possible. We might be not quite there yet but this guide will help you to ramp you up as a contributor and give you everything you need to make your first contribution. If there is any information missing that prevents you from sending in a pull request, please let us know. We treat these kind of issues like actual bugs.
Code of Conduct
Everyone who participates in this project, either as a user or a contributor, is obliged to follow the projects Code of Conduct. Every violation against it will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Find A Way To Contribute
The project offers a variety of ways to contribute. If you struggle to find something suited for you, join the WebdriverIO support channel on Matrix and reach out to the maintainer there. Don't be shy, they are there to help!
You can participate by:
- contributing code
- improving documentation
- help us translate the project to more languages
- answer questions and provide help in the Discord support channel
- create educational content (blog posts, tutorials, videos, etc.)
- spread the good word about the project (e.g. via Twitter)
- create bugs if you discover them while using WebdriverIO
- make feature requests if you are missing something in the project
- if you'd like to support us monetarily, consider donating to the project
The maintainers of the project try to organize all issues in the way that should allow anyone to have enough context to start working on it. If this is not the case please mention it in the issue thread so that either the issue creator or a maintainer can provide more information.
If you want to contribute code, a general good first way to find a task to work on is to look into all tickets with the label help wanted
and/or good first pick
. All these tickets are up for grab if they haven't a user assigned to them. If you find something that interests you, ensure to let us know in the issue thread that you have the intend to work on it.
Often issues require some amount of context to the problem which makes it difficult to get an idea about what needs to be done. Depending on your experience using / working with the project this context can be missing. Often it helps to start with tasks around missing documentation or just increase test coverage of some parts in the code. After some time you will get more familiar with the codebase which allows you to pick up more difficult tasks.
If you can't find something that suits you, look into the project roadmap to see if there is something interesting for you. At the end you can also always reach out to the maintainers in the Discord support channel. They are responsible to find a task for you.
Reporting New Issues
When opening a new issue, always make sure to fill out the issue template. This step is very important! Not doing so may result in your issue not managed in a timely fashion. Don't take this personally if this happens, and feel free to open a new issue once you've gathered all the information required by the template.
- One issue, one bug: Please report a single bug per issue.
- Provide reproduction steps: List all the steps necessary to reproduce the issue. The person reading your bug report should be able to follow these steps to reproduce your issue with minimal effort.
Providing a reproducible example
A reproducible example is a simple, self-contained script or program that demonstrates the issue or bug you're experiencing. The goal is to allow others to recreate the problem easily and efficiently.
Steps to Create a Reproducible Example:
- Isolate the Problem:
- Narrow down your code to the smallest amount that still reproduces the issue.
- Remove any non-essential code or dependencies that are not related to the problem.
- Ensure that others can run your example and reproduce the issue:
- It should not require any non-standard setup unless absolutely necessary, e.g. remove any need for special software or services like CI vendors.
- Document steps necessary to execute the reproducible example
- Share project
- Create a new public GitHub repository and push your reproducible example to it.
- Share the link to the repository in the issue.
- Document what behavior you observe and what behavior you would expect
Note: if you can't provide a reproducible example we unfortunately are forced to close the issue.
Security Bugs
See SECURITY.md.
Flowcharts
The flowcharts provide a high level overview of the WebdriverIO ecosystem and how the different packages interact with each other.
WDIO Commands - Explains the wdio config, install and repl command workflows.
Create local worker process - Explains the interaction between the @wdio/cli, @wdio/local-runner and @wdio/runner packages and how a worker process is created.
Test execution - Overview of how the tests are run in the local runner worker process.
High level overview - Flow chart provides a high level overview of how the WebdriverIO ecosystem interacts with the core packages.
Proposing a Change
We are happy for every idea you have that improves the usability of the framework. If you have an idea about a new feature please raise a feature request first to get feedback by the maintainer team on it. This lets us reach an agreement on your proposal before you put significant effort into it.
If you’re only fixing a bug, it’s fine to submit a pull request right away, but we still recommend to file an issue detailing what you’re fixing. This is helpful in case we don’t accept that specific fix but want to keep track of the issue.
Work With The Code
If you make any changes to the code, you want to test it quickly to see if they do what you expect. There are a couple of ways to do that in WebdriverIO. For one, you can link single sub-packages into your own project to see if the changes you've made have the effect you expected.
Another way to test changes in WebdriverIO is by using its example directory or by running its smoke test suite. The example directory is a set of sample scripts that use WebdriverIO in various of ways. Here, you need to have a browser driver running to run the scripts. With the smoke test suite you can run various flavors of WebdriverIO within a predefined execution scenario. All of these scenarios are defined in our WebDriver Mock Service that mimics a browser driver by stubbing the endpoints with predefined responses. It is a great way to run WebdriverIO suites quickly without having to setup anything.
Make a Pull Request
Once you have a fix implemented or finished a feature implementation you can make a pull request. Your changes needs to be pushed on your WebdriverIO fork. In the GitHub UI you should see a button popping up that allows you to raise a PR to the main repository.
We already provide a template for you to fill out. There are not many rules to follow here. Just try to explain your change with as much detail as possible. Make sure that you have written enough unit tests for your changes otherwise the code coverage check will let the build fail.
Like in many Open Source projects we ask you to sign a CLA which is a Contributor License Agreement that ensures that all contributions to the project are licensed under the project's respective open source license, which is MIT. It regulates the legal implications of you providing us (as the OpenJS Foundation) code changes.
The WebdriverIO maintainer will review your pull request as soon as possible. They will then either approve and merge your changes, request modifications or close with an explanation.
Set Up Project
You can immediately start working on the code using a pre-setup Gitpod environment (read more on this here). If you like to develop on the project locally follow this step by step guide:
-
Fork the project.
-
Clone the project somewhere on your computer
$ git clone git@github.com:<your-username>/webdriverio.git
-
On Windows, you need to set git config
core.symlinks
totrue
as we currently have some symbolic links for type definition committed to our repo.- To set git config globally:
git config --global --add core.symlinks true
- To set git config locally when cloning the repo:
git -c core.symlinks=true clone git@github.com:<your-username>/webdriverio.git
.
See https://github.com/git-for-windows/git/wiki/Symbolic-Links for more information
- To set git config globally:
-
If you need to update your fork you can do so following the steps here
-
Switch to the most recent Node LTS (you should be able to use older/newer versions of Node but we recommend to use v20 LTS so all developers are on the same side) or to the one denoted in
.nvmrc
. We recommend to usenvm
to switch between Node.js versions. -
Set up the project: First make sure you have the right Node.js version installed. You can find the current defined development version in
.nvmrc
within the root directory of the project. The easiest way to handle multiple Node.js versions is by using NVM. Once NVM is set up, use it to install the required Node.js version:$ nvm install
Next, install
pnpm
globally:$ npm install -g pnpm
Finally, set up the project via:
$ pnpm install
$ pnpm run setupThe second command does two things:
-
Cleans (possible) existing build artifacts via
pnpm run clean
If you have compiled the code this command will remove them as well as all dependencies of the subpackages.
-
Compiles the project
pnpm run compile:all
As the last step you need to build all sub-packages in order to resolve the internal dependencies. WebdriverIO uses
@wdio/compiler
which is an internal package that uses Esbuild to compile the project.
-
-
Run Tests to ensure that everything is set up correctly
# run the complete unit test suite
$ pnpm test
# run test for a specific sub project (e.g. webdriver)
$ npx vitest ./packages/webdriver/testsIt should give you a passing result. Now you can move on to set up your development environment and start working on some code. If tests do not pass please create an issue and provide logs to the error.
Work On Packages
If you start making changes to specific packages, make sure you listen to file changes and transpile the code every time you press save. To do that for all packages, run:
pnpm run dev
If you only work on a single package, you can watch only for that one by calling:
# e.g. `$ pnpm run dev wdio-runner`
$ pnpm run dev <package-name>
It is also a good idea to run vitest in watch mode while developing on a single package to see if changes affect any tests:
npx vitest ./packages/<package-name>/tests
TypeScript Definitions
WebdriverIO uses TypeScript to ensure that code is statically typed and common mistakes misusing them are avoided. If you are new to TypeScript have a look at these awesome essential resources to get started with it.
WebdriverIO provides its own type definitions for projects that use TypeScript. Given the large amount of commands it would make it unmaintainable to not automate the process of generating these. However there are certain edge cases where manual work is required.
All type definitions are generated by the TypeScript compiler. There are some essential packages for that:
- the
@wdio/types
package provides all general types that are used across the code based, e.g. Capabilities, Options etc. If you need a type definitions across multiple packages it is a good idea to define them in here - the
@wdio/protocol
package defines all protocol commands, their function parameters and return types - all other types should be defined in the package where they are used, here we tend to have general types defined in a
types.ts
file
The protocol types are generated as part of the @wdio/compiler
build command and is part of the generate-types
plugin.
Test Changes
For the development on the WebdriverIO code base you can use examples files that have been created by the maintainers in the examples directory. They cover various use cases and are setup so that they a run with the code from the repository. Let's say you make changes to the WDIO testrunner and want to see if they are applied correctly you can just run the testrunner examples by calling:
cd ./examples/wdio
$ pnpm run test:mocha
This will run a simple test suite using the testrunner with Mochajs. There are similar examples for other frameworks, custom services and reporters as well as using the devtools protocol as the automation engine. Feel free to add examples if they help testing features you are working on.
Test Pipeline
When a PR gets submitted, WebdriverIO runs the following checks:
- Dependency Checks
We automatically check if every sub-package has all the dependencies from its
package.json
installed. You can manually trigger this check by calling:$ pnpm run test:depcheck
- ESLint
A common ESLint test to align code styles and detect syntax errors early.
You can manually trigger this check by calling:
$ pnpm run test:eslint
- TypeScript Definition Tests
As we generate our type definitions, we want to be cautious that the generated definitions actually define the interface as expected. Read more
on that at Testing Type Definitions.
You can manually trigger this check by calling:
$ pnpm run test:typings
- Unit Tests
Like every project we unit-test our code and ensure that new patches are properly tested. The coverage threshold is pretty high so ensure that
your changes cover all necessary code paths. We are using Vitest as a unit test framework here.
You can manually trigger this check by calling:
$ pnpm run test:unit
- Smoke Tests
While unit tests already cover a lot of cases, we run in addition to that smoke tests that simulate test scenarios which are difficult to test
on a unit level as they include functionality of dependencies that are stubbed out in unit tests. Such scenarios are, for example, proper
test retries or failure handling. Smoke tests run actual e2e tests where the driver is being stubbed (via
@wdio/smoke-test-service
) to return fake results. You can manually trigger this check by calling:$ pnpm run test:smoke
- e2e Tests
Last but not least, we run actual e2e tests with a real headless browser to ensure we can spin up tests in all support variants and that certain services from end to end.
You can manually trigger this check by calling:
$ pnpm run test:e2e
Unit Tests
The project tries to keep a high test coverage to ensure that changes to code are intentional and well thought through. Therefore "normally" there is a unit test file for every code file, located in a test directory. For example the unit tests for:
packages/webdriverio/src/commands/element/getCSSProperty.ts
are located in
packages/webdriverio/tests/commands/element/getCSSProperty.test.ts
If that is not the case the functionality of that file might be tested through a different file. We recommend to write unit tests for every new function being written in the code base. We advise to mock out every dependency to either other packages or modules using Vitests mock capabilities.
During development it makes sense to focus running unit tests for a single file rather the whole code base. For example if you work on the getCSSProperty
command it makes sense to run only the unit test for that specific command by calling:
npx vitest packages/webdriverio/tests/commands/element/getCSSProperty.test.ts
With the --watch
flag the unit tests will be re-run as soon as you change something within the file.
Run e2e Experience With Smoke Tests
WebdriverIO maintains a set of smoke test suites that allows to represent the full e2e experience of a user running the wdio testrunner. It is set up in a way so it doesn't require an actual browser driver since all requests are mocked using the @wdio/webdriver-mock-service
. This offers you an opportunity to run a wdio test suite without setting up a browser driver and a test page. You can run all smoke tests via:
pnpm run test:smoke