|
| 1 | +Cucumber Boilerplate [](https://travis-ci.org/webdriverio/cucumber-boilerplate) [](https://david-dm.org/webdriverio/cucumber-boilerplate) [](https://david-dm.org/webdriverio/cucumber-boilerplate/?type=dev) [](https://codeclimate.com/github/webdriverio/cucumber-boilerplate) [](https://codeclimate.com/github/webdriverio/cucumber-boilerplate/coverage) |
| 2 | + |
| 3 | +==================== |
| 4 | + |
| 5 | +Boilerplate project to run WebdriverIO tests with [Cucumber](https://cucumber.io/) and brings **true** [BDD](http://en.wikipedia.org/wiki/Behavior-driven_development) to JavaScript. Instead of writing complicated test code that only developers 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. |
| 6 | + |
| 7 | +# Quick start |
| 8 | + |
| 9 | +Choose one of the following options: |
| 10 | + |
| 11 | +1. Download the latest stable release [here](https://github.com/webdriverio/cucumber-boilerplate/archive/master.zip) or |
| 12 | +2. Clone the git repo — `git clone https://github.com/webdriverio/cucumber-boilerplate.git` |
| 13 | + |
| 14 | +Then just embed the test directory into the root folder of your project and copy/install the [necessary dependencies |
| 15 | +from the package.json](https://github.com/webdriverio/cucumber-boilerplate/blob/master/package.json) |
| 16 | +file and you are all set. |
| 17 | + |
| 18 | +## Features |
| 19 | + |
| 20 | +- Super simple setup |
| 21 | +- Full integration with [WebdriverIO](http://webdriver.io/) |
| 22 | +- Over 150 predefined steps that cover almost everything you need, you can start writing tests right away |
| 23 | +- Easy integration with cloud services like [Sauce Labs](https://saucelabs.com/) |
| 24 | +- Integration of WebdriverIO's Multiremote functionality |
| 25 | +- Easy to run tests in parallel |
| 26 | + |
| 27 | +# How to write a test |
| 28 | + |
| 29 | +Tests are written in [Gherkin syntax](http://docs.behat.org/en/latest/guides/1.gherkin.html#gherkin-syntax) |
| 30 | +that means that you write down what's supposed to happen in a real language. All test files are located in |
| 31 | +`./test/features/*` and have the file ending `.feature`. You will already find some test files in that |
| 32 | +directory. They should demonstrate, how tests could look like. Just create a new file and write your first |
| 33 | +test. |
| 34 | + |
| 35 | +__myFirstTest.feature__ |
| 36 | +```gherkin |
| 37 | +Feature: |
| 38 | + In order to keep my product stable |
| 39 | + As a developer or product manager |
| 40 | + I want to make sure that everything works as expected |
| 41 | +
|
| 42 | +Scenario: Check title of website after search |
| 43 | + Given I open the url "http://google.com" |
| 44 | + When I set "WebdriverIO" to the inputfield "#gbqfq" |
| 45 | + And I press "Enter" |
| 46 | + Then I expect that the title is "WebdriverIO - Google Search" |
| 47 | +
|
| 48 | +Scenario: Another test |
| 49 | + Given ... |
| 50 | +
|
| 51 | +``` |
| 52 | + |
| 53 | +This test opens the browser and navigates them to google.com to check if the title contains the search |
| 54 | +query after doing a search. As you can see, it is pretty simple and understandable for everyone. |
| 55 | + |
| 56 | +# How to run the test |
| 57 | + |
| 58 | +Start the local web server: |
| 59 | + |
| 60 | +```sh |
| 61 | +$ npm run-script local-webserver |
| 62 | +``` |
| 63 | + |
| 64 | +To run your tests just call the [WDIO runner](http://webdriver.io/guide/testrunner/gettingstarted.html): |
| 65 | + |
| 66 | +```sh |
| 67 | +$ wdio |
| 68 | +``` |
| 69 | + |
| 70 | +_please note_ The WDIO runner uses the configuration file `wdio.conf.js` by default. |
| 71 | + |
| 72 | +# Configurations |
| 73 | + |
| 74 | +To configure your tests, checkout the [`wdio.conf.js`](https://github.com/webdriverio/cucumber-boilerplate/blob/master/wdio.conf.js) file in your test directory. It comes with a bunch of documented options you can choose from. |
| 75 | + |
| 76 | +## Environment-specific configurations |
| 77 | + |
| 78 | +You can setup multiple configs for specific environments. Let's say you want to have a different `baseUrl` for |
| 79 | +your local and pre-deploy tests. Use the `wdio.conf.js` to set all general configs (like mochaOpts) that don't change. |
| 80 | +They act as default values. For each different environment you can create a new config with the following name |
| 81 | +scheme: |
| 82 | + |
| 83 | +```txt |
| 84 | +wdio.<ENVIRONMENT>.conf.js |
| 85 | +``` |
| 86 | + |
| 87 | +Now you can create a specific config for your pre-deploy tests: |
| 88 | + |
| 89 | +__wdio.STAGING.conf.js__ |
| 90 | +```js |
| 91 | +var config = require('./wdio.conf.js').config; |
| 92 | + |
| 93 | +config.baseUrl = 'http://staging.example.com' |
| 94 | + |
| 95 | +exports.config = config; |
| 96 | +``` |
| 97 | + |
| 98 | +Your environment-specific config file will get merged into the default config file and overwrites the values you set. |
| 99 | +To run a test in a specific environment just add the desired configuration file as the first parameter: |
| 100 | + |
| 101 | +```sh |
| 102 | +$ wdio wdio.STAGING.conf.js |
| 103 | +``` |
| 104 | + |
| 105 | +# Running single feature |
| 106 | +Sometimes its usefull to only execute a single feature file, to do so use the following command: |
| 107 | + |
| 108 | +```sh |
| 109 | +$ wdio --spec ./test/features/select.feature |
| 110 | +``` |
| 111 | + |
| 112 | + |
| 113 | +# Using tags |
| 114 | + |
| 115 | +If you want to run only specific tests you can mark your features with tags. These tags will be placed before each feature like so: |
| 116 | + |
| 117 | +```gherkin |
| 118 | +@Tag |
| 119 | +Feature: ... |
| 120 | +``` |
| 121 | + |
| 122 | +To run only the tests with specific tag(s) use the `--tags=` parameter like so: |
| 123 | + |
| 124 | +```sh |
| 125 | +$ wdio --tags=@Tag,@AnotherTag |
| 126 | +``` |
| 127 | + |
| 128 | +You can add multiple tags separated by a comma |
| 129 | + |
| 130 | +# Pending test |
| 131 | + |
| 132 | +If you have failing or unimplemented tests you can mark them as "Pending" so they will get skipped. |
| 133 | + |
| 134 | +```gherkin |
| 135 | +// skip whole feature file |
| 136 | +@Pending |
| 137 | +Feature: ... |
| 138 | +
|
| 139 | +// only skip a single scenario |
| 140 | +@Pending |
| 141 | +Scenario: ... |
| 142 | +``` |
| 143 | + |
| 144 | +# Adding new steps and snippets |
| 145 | + |
| 146 | +The predefined snippets allow you to do a lot of common things but you might need extra snippets which |
| 147 | +are better aligned with your aims. To do so you will find all step definitions in `./test/steps`. They |
| 148 | +are separated in `given`, `when` and `then`. |
| 149 | + |
| 150 | +You define your snippet using regular expressions. This is pretty powerful as it allows you to create complex |
| 151 | +sentences with multiple options. Everything that's within `"([^"]*)?"` gets captured and appended to the |
| 152 | +callback. The last argument is always a callback function that you need to call when your step is done. |
| 153 | +You can access the browser and your WebdriverIO instance with `browser`. |
| 154 | + |
| 155 | +To assert values this boilerplate project comes with a [Chai](http://chaijs.com/) integration. |
| 156 | + |
| 157 | +# Comments |
| 158 | + |
| 159 | +You can add additional descriptive comments in your feature files. |
| 160 | + |
| 161 | +```gherkin |
| 162 | +### |
| 163 | + This is a |
| 164 | + block comment |
| 165 | +### |
| 166 | +Feature: As a bystander |
| 167 | + I can watch bottles falling from a wall |
| 168 | + So that I can be mildly amused |
| 169 | +
|
| 170 | +# This is a single line comment |
| 171 | +Scenario: check if username is present |
| 172 | + Given I login as "roboter" with password "test123" |
| 173 | + Then the username "roboter" should be present in the header |
| 174 | +``` |
| 175 | + |
| 176 | +# List of predefined steps |
| 177 | + |
| 178 | +Check out all predefined snippets. You can see how they get used in [`sampleSnippets.feature`](https://github.com/webdriverio/cucumber-boilerplate/blob/master/test/features/sampleSnippets.feature). |
| 179 | + |
| 180 | +## Given steps |
| 181 | + |
| 182 | +- `I open the (url|site) "([^"]*)?"` <br>Open a site in the current browser window/tab |
| 183 | +- `the element "([^"]*)?" is( not)* visible` <br>Check the (in)visibility of a element |
| 184 | +- `the element "([^"]*)?" is( not)* enabled` <br>Check if a element is (not) enabled |
| 185 | +- `the element "([^"]*)?" is( not)* selected` <br>Check if a element is (not) selected |
| 186 | +- `the checkbox "([^"]*)?" is( not)* checked` <br>Check if a checkbox is (not) checked |
| 187 | +- `there is (an|no) element "([^"]*)?" on the page` <br>Check if a element (does not) exist |
| 188 | +- `the title is( not)* "([^"]*)?"` <br>Check the title of the current browser window/tab |
| 189 | +- `the element "([^"]*)?" contains( not)* the same text as element "([^"]*)?"` <br>Compaire the text of two elements |
| 190 | +- `the (element|inputfield) "([^"]*)?" does( not)* contain the text "([^"]*)?"` <br>Check if a element contains the given text |
| 191 | +- `the (element|inputfield) "([^"]*)?" does( not)* contain any text` <br>Check if a element does not contain any text |
| 192 | +- `the page url is( not)* "([^"]*)?"` <br>Check the url of the current browser window/tab |
| 193 | +- `the( css)* attribute "([^"]*)?" from element "([^"]*)?" is( not)* "([^"]*)?"` <br>Check the value of a element's (css) attribute |
| 194 | +- `the cookie "([^"]*)?" contains( not)* the value "([^"]*)?"` <br>Check the value of a cookie |
| 195 | +- `the cookie "([^"]*)?" does( not)* exist` <br>Check the existence of a cookie |
| 196 | +- `the element "([^"]*)?" is( not)* ([\d]+)px (broad|tall)` <br>Check the width/height of a element |
| 197 | +- `the element "([^"]*)?" is( not)* positioned at ([\d]+)px on the (x|y) axis` <br>Check the position of a element |
| 198 | +- `I have a screen that is ([\d]+) by ([\d]+) pixels` <br>Set the browser size to a given size |
| 199 | +- `I have closed all but the first (window|tab)` <br>Close all but the first browser window/tab |
| 200 | +- `a (alertbox|confirmbox|prompt) is( not)* opened` <br>Check if a modal is opened |
| 201 | + |
| 202 | +## Then steps |
| 203 | + |
| 204 | +- `I expect that the title is( not)* "([^"]*)?"` <br>Check the title of the current browser window/tab |
| 205 | +- `I expect that element "([^"]*)?" is( not)* visible` <br>Check if a certain element is visible |
| 206 | +- `I expect that element "([^"]*)?" becomes( not)* visible` <br>Check if a certain element becomes visible |
| 207 | +- `I expect that element "([^"]*)?" is( not)* within the viewport` <br>Check if a certain element is within the current viewport |
| 208 | +- `I expect that element "([^"]*)?" does( not)* exist` <br>Check if a certain element exists |
| 209 | +- `I expect that element "([^"]*)?" does( not)* contain the same text as element "([^"]*)?"` <br>Compare the text of two elements |
| 210 | +- `I expect that (element|inputfield) "([^"]*)?"( not)* contains the text "([^"]*)?"` <br>Check if a element or input field contains the given text |
| 211 | +- `I expect that (element|inputfield) "([^"]*)?" does( not)* contain any text` <br>Check if a element or input field contains any text |
| 212 | +- `I expect that (element|inputfield) "([^"]*)?" is( not)* empty` <br>Check if a element or input field is empty |
| 213 | +- `I expect that the url is( not)* "([^"]*)?"` <br>Check if the the URL of the current browser window/tab is a certain string |
| 214 | +- `I expect that the path is( not)* "([^"]*)?"` <br>Check if the path of the URL of the current browser window/tab is a certain string |
| 215 | +- `I expect the url to( not)* contain "([^"]*)?"` <br>Check if the URL of the current browser window/tab contains a certain string |
| 216 | +- `I expect that the( css)* attribute "([^"]*)?" from element "([^"]*)?" is( not)* "([^"]*)?"` <br>Check the value of a element's (css) attribute |
| 217 | +- `I expect that checkbox "([^"]*)?" is( not)* checked` <br>Check if a check-box is (not) checked |
| 218 | +- `I expect that element "([^"]*)?" is( not)* selected` <br>Check if a element is (not) selected |
| 219 | +- `I expect that element "([^"]*)?" is( not)* enabled` <br>Check if a element is (not) enabled |
| 220 | +- `I expect that cookie "([^"]*)?"( not)* contains "([^"]*)?"` <br>Check if a cookie with a certain name contains a certain value |
| 221 | +- `I expect that cookie "([^"]*)?"( not)* exists` <br>Check if a cookie with a certain name exist |
| 222 | +- `I expect that element "([^"]*)?" is( not)* ([\d]+)px (broad|tall)` <br>Check the width/height of an element |
| 223 | +- `I expect that element "([^"]*)?" is( not)* positioned at ([\d]+)px on the (x|y) axis` <br>Check the position of an element |
| 224 | +- `I expect that element "([^"]*)?" (has|does not have) the class "([^"]*)?"` <br>Check if a element has a certain class |
| 225 | +- `I expect a new (window|tab) has( not)* been opened` <br>Check if a new window/tab has been opened |
| 226 | +- `I expect the url "([^"]*)?" is opened in a new (tab|window)` <br>Check if a URL is opened in a new browser window/tab |
| 227 | +- `I expect that element "([^"]*)?" is( not)* focused` <br>Check if a element has the focus |
| 228 | +- `I wait on element "([^"]*)?"( for (\d+)ms)*( to( not)* (be checked|be enabled|be selected|be visible|contain a text|contain a value|exist))*` <br>Wait for a element to be checked, enabled, selected, visible, contain a certain value or text or to exist |
| 229 | +- `I expect that a (alertbox|confirmbox|prompt) is( not)* opened` <br>Check if a modal is opened |
| 230 | +- `I expect that a (alertbox|confirmbox|prompt)( not)* contains the text "$text"` <br>Check the text of a modal |
| 231 | + |
| 232 | +## When steps |
| 233 | + |
| 234 | +- `I (click|doubleclick) on the (link|button|element) "([^"]*)?"` <br>(Double)click a link, button or element |
| 235 | +- `I (add|set) "([^"]*)?" to the inputfield "([^"]*)?"` <br>Add or set the content of an input field |
| 236 | +- `I clear the inputfield "([^"]*)?"` <br>Clear an input field |
| 237 | +- `I drag element "([^"]*)?" to element "([^"]*)?"` <br>Drag a element to another element |
| 238 | +- `I submit the form "([^"]*)?"` <br>Submit a form |
| 239 | +- `I pause for (\d+)ms` <br>Pause for a certain number of milliseconds |
| 240 | +- `I set a cookie "([^"]*)?" with the content "([^"]*)?"` <br>Set the content of a cookie with the given name to the given string |
| 241 | +- `I delete the cookie "([^"]*)?"` <br>Delete the cookie with the given name |
| 242 | +- `I press "([^"]*)?"` <br>Press a given key. You’ll find all supported characters [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value). To do that, the value has to correspond to a key from the table. |
| 243 | +- `I (accept|dismiss) the (alertbox|confirmbox|prompt)` <br>Accept or dismiss a modal window |
| 244 | +- `I enter "([^"]*)?" into the prompt` <br>Enter a given text into a modal prompt |
| 245 | +- `I scroll to element "([^"]*)?"` <br>Scroll to a given element |
| 246 | +- `I close the last opened (window|tab)` <br>Close the last opened browser window/tab |
| 247 | +- `I focus the last opened (window|tab)` <br>Focus the last opened browser window/tab |
| 248 | +- `I log in to site with username "([^"]*)?" and password "([^"]*)?"` <br>Login to a site with the given username and password |
| 249 | +- `I select the (\d+)(st|nd|rd|th) option for element "([^"]*)?"` <br>Select a option based on it's index |
| 250 | +- `I select the option with the (name|value|text) "([^"]*)?" for element "([^"]*)?"` <br>Select a option based on it's name, value or visible text |
| 251 | +- `I move to element "([^"]*)?"( with an offset of (\d+),(\d+))` <br>Move the mouse by an (optional) offset of the specified element |
0 commit comments