Boilerplate project to run WebdriverIO tests with Cucumber. It is based on a framework called yadda and brings true BDD to JavaScript and WebdriverIO. Instead of writing complicated test code that only devs can understand, Cucumber maps an ordinary language to code and allows to start with the test process in the early stages of your product development.
Choose one of the following options:
- Download the latest stable release here or
- Clone the git repo —
git clone https://github.com/webdriverio/cucumber-boilerplate.git
Then just embed the test directory into the root folder of your project and copy/install the necessary dependencies from the package.json file and you are all set.
- Super simple setup
- Full integration with WebdriverIO
- Over 150 predefined steps that cover almost everything you need, you can start writing tests right away
- Easy integration with cloud services like Sauce Labs
- Support for different languages (French, Spanish, Norwegian, Polish, German, Russian)
- Integration of WebdriverIO's Multiremote functionality (coming soon)
- Easy to run tests in parallel (coming soon)
Tests are written in Gherkin syntax
that means that you write down what's supposed to happen in a real language. All test files are located in
./test/features/*
and have the file ending .feature
. You will already find some test files in that
directory. They should demonstrate, how tests could look like. Just create a new file and write your first
test.
myFirstTest.feature
Feature:
In order to keep my product stable
As a developer or product manager
I want to make sure that everything works as expected
Scenario: Check title of website after search
Given I open the url "http://google.com"
When I set "WebdriverIO" to the inputfield "#gbqfq"
And I press "Enter"
Then I expect that the title is "WebdriverIO - Google Search"
Scenario: Another test
Given ...
This test opens the browser and navigates them to google.com to check if the title contains the search query after doing a search. As you can see, it is pretty simple and understandable for everyone.
Start the selenium server:
$ npm run-script selenium-server
Start the local web server:
$ npm run-script local-webserver
To run your tests just call the run.js file:
$ ./test/run.js
To configure your tests, checkout the config.js
file in your test directory. It comes with a bunch of documented options you can choose from.
You can setup multiple configs for specific environments. Let's say you want to have a different baseUrl
for
your local and pre-deploy tests. Use the config.js
to set all general configs (like mochaOpts) that don't change.
They act as default values. For each different environment you can create a new config with the following name
scheme:
config.<ENVIRONMENT>.js
Now you can create a specific config for your pre-deploy tests:
config.staging.js
module.config = {
baseUrl: 'http://staging.example.com'
}
Your environment-specific config file will get merged into the default config file and overwrites the values you set.
To run a test in a specific environment just set the desired NODE_ENV
environment variable:
$ NODE_ENV=staging ./test/run.js
The predefined snippets allow you to do a lot of common things but you might need extra snippets which
are better aligned with your aims. To do so you will find all step definitions in ./test/steps
. They
are separated in given
, when
and then
. For instance if you want to have a login step that helps
you to login the browser before each test, you can start to add that as a given
snippet:
./test/steps/given.js
module.exports = function() {
this.given(/I open the (url|site) "$string"$/, function (type, page, done) {
var url = type === 'url' ? page : this.baseUrl + page;
this.browser.url(url , done);
})
// ... other predefined snippets
// ...
// ...
/**
* my login snippet
*/
.given(/^I login as "$string" with password "$string"$/, function(username, password, done) {
this.browser
.setInput('input#username', username)
.setInput('input#password', password)
.submitForm('#login')
.call(done);
})
You define your snippet using regular expressions. This is pretty powerful as it allows you to create complex
sentences with multiple options. Everything that's within "$string"
gets captured and appended to the
callback. The last argument is always a callback function that you need to call when your step is done.
You can access the browser and your WebdriverIO instance with this.browser
.
To assert values this boilerplate project comes with a Chai integration. Let's say you want to check if the username gets display in the header properly. For that we add a new snippet in
./test/steps/then.js
module.exports = function(dict) {
this.then(/^I expect that the title is( not)* "$string"$/,
require('../support/helper/checkTitle'))
// ... other predefined snippets
// ...
// ...
/**
* my check username in header snippet
*/
.then(/^the username "$string" should be present in the header$/, function(username, done) {
client.getText('#header .username', function(err, headerUsername) {
should.not.exist(err);
username.should.equal(headerUsername, 'username in header doesn\'t match');
})
.call(done);
})
That's it. We created two new snippets to test something on our page. We can use these snippets now in our Scenario like this:
Feature: ...
Scenario: check if username is present
Given I login as "roboter" with password "test123"
Then the username "roboter" should be present in the header
You can add additional descriptive comments in your feature files.
###
This is a
block comment
###
Feature: As a bystander
I can watch bottles falling from a wall
So that I can be mildly amused
# This is a single line comment
Scenario: check if username is present
Given I login as "roboter" with password "test123"
Then the username "roboter" should be present in the header
If you have failing or unimplemented tests you can mark them as "Pending" so they will get skipped.
// skip whole feature file
@Pending
Feature: ...
// only skip a single scenario
@Pending
Scenario: ...
If you want to run just a single test and ignore the others you can use the @Only
annotation.
// run test is isolation
@Only
Scenario: ...
If there are more tests to isolate use the @Isolate
annotation.
// run only the "isolated" scenarios
@Isolate
Scenario: ...
Scenario: ...
...
@Isolate
Scenario: ...
Check out all predefined snippets. You can see how they get used in sampleSnippets.feature
.
/I open the (url|site) "$string"
Open a site in the current browser window/tabthe element "$string" is( not)* visible
Check the (in)visibility of a elementthe element "$string" is( not)* enabled
Check if a element is (not) enabledthe element "$string" is( not)* selected
Check if a element is (not) selectedthe checkbox "$string" is( not)* checked
Check if a checkbox is (not) checkedthere is (an|no) element "$string" on the page
Check if a element (does not) existthe title is( not)* "$string"
Check the title of the current browser window/tabthe element "$string" contains( not)* the same text as element "$string"
Compaire the text of two elementsthe (element|inputfield) "$string" does( not)* contain the text "$string"
Check if a element contains the given textthe (element|inputfield) "$string" does( not)* contain any text
Check if a element does not contain any textthe page url is( not)* "$string"
Check the url of the current browser window/tabthe( css)* attribute "$string" from element "$string" is( not)* "$string"
Check the value of a element's (css) attributethe cookie "$string" contains( not)* the value "$string"
Check the value of a cookiethe cookie "$string" does( not)* exist
Check the existence of a cookiethe element "$string" is( not)* ([\d]+)px (broad|tall)
Check the width/height of a elementthe element "$string" is( not)* positioned at ([\d]+)px on the (x|y) axis
Check the position of a elementI have a screen that is ([\d]+) by ([\d]+) pixels
Set the browser size to a given sizeI have closed all but the first (window|tab)
Close all but the first browser window/taba (alertbox|confirmbox|prompt) is( not)* opened
Check if a modal is opened
I expect that the title is( not)* "$string"
Check the title of the current browser window/tabI expect that element "$string" is( not)* visible
Check if a certain element is visibleI expect that element "$string" becomes( not)* visible
Check if a certain element becomes visibleI expect that element "$string" is( not)* within the viewport
Check if a certain element is within the current viewportI expect that element "$string" does( not)* exist
Check if a certain element existsI expect that element "$string" does( not)* contain the same text as element "$string"
Compaire the text of two elementsI expect that (element|inputfield) "$string"( not)* contains the text "$string"
Check if a element or input field contains the given textI expect that (element|inputfield) "$string" does( not)* contain any text
Check if a element or input field contains any textI expect that (element|inputfield) "$string" is( not)* empty
Check if a element or input field is emptyI expect that the url is( not)* "$string"
Check if the the url of the current browser window/tab is a certain stringI expect that the path is( not)* "$string"
Check if the path of the url of the current browser window/tab is a certain stringI expect the url to( not)* contain "$string"
Check if the url of the current browser window/tab contains a certain stringI expect that the( css)* attribute "$string" from element "$string" is( not)* "$string"
Check the value of a element's (css) attributeI expect that checkbox "$string" is( not)* checked
Check if a checkbox is (not) checkedI expect that element "$string" is( not)* selected
Check if a element is (not) selectedI expect that element "$string" is( not)* enabled
Check if a element is (not) enabledI expect that cookie "$string"( not)* contains "$string"
Check if a cookie with a certain name contains a certain valueI expect that cookie "$string"( not)* exists
Check if a cookie with a certain name existI expect that element "$string" is( not)* ([\d]+)px (broad|tall)
Check the width/height of an elementI expect that element "$string" is( not)* positioned at ([\d]+)px on the (x|y) axis
Check the position of an elementI expect that element "$string" (has|does not have) the class "$string"
Check if a element has a certain classI expect a new (window|tab) has( not)* been opened
Check if a new window/tab has been openedI expect the url "$string" is opened in a new (tab|window)
Check if a url is opened in a new browser window/tabI expect that element "$string" is( not)* focused
Check if a element has the focusI wait on element "$string"( for (\d+)ms)*( to( not)* (be checked|be enabled|be selected|be visible|contain a text|contain a value|exist))*
Wait for a element to be checked, enabled, selected, visible, contain a certain value or text or to existI expect that a (alertbox|confirmbox|prompt) is( not)* opened
Check if a modal is openedI expect that a (alertbox|confirmbox|prompt)( not)* contains the text "$text"
Check the text of a modal
I (click|doubleclick) on the (link|button|element) "$string"
(Double)click a link, button or elementI (add|set) "$string" to the inputfield "$string"
Add or set the content of an input fieldI clear the inputfield "$string"
Clear an input fieldI drag element "$string" to element "$string"
Drag a element to another elementI submit the form "$string"
Submit a formI pause for (\d+)ms
Pause for a certain number of millisecondsI set a cookie "$string" with the content "$string"
Set the content of a cookie with the given name to the given stringI delete the cookie "$string"
Delete the cookie with the given nameI press "$string"
Press a given key. You’ll find all supported characters here. To do that, the value has to correspond to a key from the table.I (accept|dismiss) the (alertbox|confirmbox|prompt)
Accept or dismiss a modal windowI enter "$string" into the prompt
Enter a given text into a modal promptI scroll to element "$string"
Scroll to a given elementI close the last opened (window|tab)
Close the last opened browser window/tabI focus the last opened (window|tab)
Focus the last opened browser window/tabI log in to site with username "$string" and password "$string"
Login to a site with the given username and passwordI select the (\d+)(st|nd|rd|th) option for element "$string"
Select a option based on it's indexI select the option with the (name|value|text) "$string" for element "$string"
Select a option based on it's name, value or visible text
Please fork, add specs, and send pull requests! In lieu of a formal style guide, take care to maintain the existing coding style. Currently not all WebdriverIO commands are mapped and implemented as snippets. Any contributions that adds new snippets + test are highly welcome.