diff --git a/docs/acceptance.md b/docs/acceptance.md
index 736169350..b462d2069 100644
--- a/docs/acceptance.md
+++ b/docs/acceptance.md
@@ -2,16 +2,13 @@
How does your client, manager, or tester, or any other non-technical person, know your web application is working? By opening the browser, accessing a site, clicking on links, filling in the forms, and actually seeing the content on a web page.
-Acceptance (also called End to End) tests can cover standard but complex scenarios from a user's perspective. With acceptance tests you can be confident that users, following all defined scenarios, won't get errors. We check **not just functionality of application but a user interface** (UI) as well.
+*Acceptance tests* (also called *End-to-End tests*) can cover standard but complex scenarios from a user's perspective. With acceptance tests you can be confident that users, following all defined scenarios, won't get errors. We check **not just functionality of application but a user interface** (UI) as well.
-By default CodeceptJS uses [WebDriver](/helpers/WebDriver/) helper and **Selenium** to automate browser. Within web page you can locate elements, interact with them, and check that expected elements are present on a page.
-However, you can also choose [Nightmare](/helpers/Nightmare) or [Protractor](/helpers/Protractor) helpers, driven by corresponding libraries.
-No matter of helper and library you use for acceptance testing, CodeceptJS should execute same actions in similar manner.
+No matter of helper and driver you use for acceptance testing, CodeceptJS should execute same actions in similar manner.
-In case of CodeceptJS you can be sure that in code it will be as easy as it sounds. You just describe a test scenario with JavaScript DSL and allow the framework to handle the rest.
+In case of CodeceptJS you can be sure that in code it will be as easy as it sounds. You just describe a test scenario with JavaScript and allow the framework to handle the rest.
Within web page you can locate elements, interact with them, and check that expected elements are present on a page. That is what a test look like.
-That is what a test look like.
```js
I.amOnPage('/login');
@@ -21,7 +18,7 @@ I.click('Login');
I.see('Welcome, John');
```
-This is how we can check that login form of a simple web application works. At first we opened `/login` page, then filled forms and in the end we saw the greetings text.
+This is how we can check that login form of a simple web application works. At first we opened the `/login` page, then filled in form fields, clicked a button, and in the end we check that we saw the greeting text.
## Locating Element
@@ -50,7 +47,7 @@ I.seeElement({name: 'password'});
I.seeElement({id: 'users'});
```
-In [mobile testing](http://codecept.io/mobile/#locating-elements) you can use `~` to specify accessibility id to locate an element. In web application you can locate element by their `aria-label` value.
+In [mobile testing](mobile.md#locating-elements) you can use `~` to specify accessibility id to locate an element. In web application you can locate element by their `aria-label` value.
```js
// locate element by [aria-label] attribute in web
@@ -247,7 +244,7 @@ If it's hard to define what to wait, it is recommended to use [retries](https://
## IFrames
-[within](/basics/#within) operator can be used to work inside IFrames. Special `frame` locator is required to locate the iframe and get into its context.
+[within](locators.md#within) operator can be used to work inside IFrames. Special `frame` locator is required to locate the iframe and get into its context.
See example:
@@ -265,80 +262,9 @@ within({frame: [".content", "#editor"]}, () => {
});
```
-## Multiple Sessions
-
-CodeceptJS allows to run several browser sessions inside a test. This can be useful for testing communication between users inside a system, for instance in chats. To open another browser use `session()` function as shown in example:
-
-```js
-Scenario('test app', (I) => {
- I.amOnPage('/chat');
- I.fillField('name', 'davert');
- I.click('Sign In');
- I.see('Hello, davert');
- session('john', () => {
- // another session started
- I.amOnPage('/chat');
- I.fillField('name', 'john');
- I.click('Sign In');
- I.see('Hello, john');
- });
- // switching back to default session
- I.fillField('message', 'Hi, john');
- // there is a message from current user
- I.see('me: Hi, john', '.messages');
- session('john', () => {
- // let's check if john received it
- I.see('davert: Hi, john', '.messages');
- });
-});
-```
-
-`session` function expects a first parameter to be a name of a session. You can switch back to session by using the same name.
-
-You can override config for session by passing second parameter:
-
-```js
-session('john', { browser: 'firefox' } , () => {
- // run this steps in firefox
- I.amOnPage('/');
-});
-```
-
-or just start session without switching to it. Call `session` passing only its name:
-
-```js
-Scenario('test', (I) => {
- // opens 3 additional browsers
- session('john');
- session('mary');
- session('jane');
-
- I.amOnPage('/');
-
- // switch to session by its name
- session('mary', () => {
- I.amOnPage('/login');
- });
-}
-```
-`session` can return value which can be used in scenario:
-
-```js
-// inside async function
-const val = await session('john', () => {
- I.amOnPage('/info');
- return I.grabTextFrom({ css: 'h1' });
-});
-I.fillField('Description', val);
-```
-
-Function passed into session can use `I`, page objects, and any objects declared for the scenario.
-This function can also be declared as async (but doesn't work as generator).
-
-Also, you can use `within` inside a session but you can't call session from inside `within`.
---
-### done()
+### Next: [BDD Testing >>>](bdd.md)
-CodeceptJS through helpers provides user friendly API to interact with a webpage. In this section we described using WebDriver helper which allows to control browser through Selenium WebDriver.
+---
diff --git a/docs/advanced.md b/docs/advanced.md
index 7364a90d3..0aae3ce5e 100644
--- a/docs/advanced.md
+++ b/docs/advanced.md
@@ -1,81 +1,5 @@
# Advanced Usage
-## Data Driven Tests
-
-Execute the same scenario on a different data set.
-
-Let's say you want to test login for different user accounts.
-In this case, you need to create a datatable and fill it in with credentials.
-Then use `Data().Scenario` to include this data and generate multiple scenarios:
-
-```js
-// Define data table inside a test or load from another module
-let accounts = new DataTable(['login', 'password']); //
-accounts.add(['davert', '123456']); // adding records to a table
-accounts.add(['admin', '123456']);
-
-// You can skip some data. But add them to report as skipped (just like with usual scenarios):
-accounts.xadd(['admin', '23456'])
-
-// Pass dataTable to Data()
-// Use special param `current` to get current data set
-Data(accounts).Scenario('Test Login', (I, current) => {
- I.fillField('Username', current.login); // current is reserved!
- I.fillField('Password', current.password);
- I.click('Sign In');
- I.see('Welcome '+ current.login);
-});
-
-
-// Also you can set only for Data tests. It will launch executes only the current test but with all data options
-Data(accounts).only.Scenario('Test Login', (I, current) => {
- I.fillField('Username', current.login); // current is reserved!
- I.fillField('Password', current.password);
- I.click('Sign In');
- I.see('Welcome '+ current.login);
-});
-```
-
-*Important: you can't use name `current` for pageObjects or helpers in data scenarios*
-
-This will produce 2 tests with different data sets.
-Current data set is appended to a test name in output:
-
-```sh
-✓ Test Login | {"login":"davert","password":"123456"}
-✓ Test Login | {"login":"admin","password":"123456"}
-S Test Login | {"login":"admin","password":"23456"}
-```
-
-```js
-// You can filter your data table
-Data(accounts.filter(account => account.login == 'admin')
-.Scenario('Test Login', (I, current) => {
- I.fillField('Username', current.login);
- I.fillField('Password', current.password);
- I.click('Sign In');
- I.see('Welcome '+ current.login);
-});
-```
-
-This will limit data sets accoring passed function:
-
-```sh
-✓ Test Login | {"login":"admin","password":"123456"}
-S Test Login | {"login":"admin","password":"23456"}
-```
-
-Data sets can also be defined with array, generator, or a function.
-
-```js
-Data(function*() {
- yield { user: 'davert'};
- yield { user: 'andrey'};
-}).Scenario() // ...
-```
-
-*HINT: If you don't use DataTable. add `toString()` method to each object added to data set, so the data could be pretty printed in a test name*
-
## Tags
Append `@tag` to your test name, so
@@ -106,208 +30,6 @@ Use regex for more flexible filtering:
* `--grep '(?=.*@smoke2)^(?!.*@smoke3)'` - run tests with @smoke2 but without @smoke3 in name
* `--grep '(?=.*)^(?!.*@smoke4)'` - run all tests except @smoke4
-
-
-## Debug
-
-CodeceptJS provides a debug mode in which additional information is printed.
-It can be turned on with `--debug` flag.
-
-```sh
-codeceptjs run --debug
-```
-
-to receive even more information turn on `--verbose` flag:
-
-```sh
-codeceptjs run --verbose
-```
-
-And don't forget that you can pause execution and enter **interactive console** mode by calling `pause()` inside your test.
-
-For advanced debugging use NodeJS debugger. In WebStorm IDE:
-
-```sh
-node $NODE_DEBUG_OPTION ./node_modules/.bin/codeceptjs run
-```
-
-For Visual Studio Code, add the following configuration in launch.json:
-
-```json
-{
- "type": "node",
- "request": "launch",
- "name": "codeceptjs",
- "args": ["run", "--grep", "@your_test_tag"],
- "program": "${workspaceFolder}/node_modules/.bin/codeceptjs"
-}
-```
-
-
-
-## Multiple Browsers Execution
-
-This is useful if you want to execute same tests but on different browsers and with different configurations or different tests on same browsers in parallel.
-
-Create `multiple` section in configuration file, and fill it with run suites. Each suite should have `browser` array with browser names or driver helper's configuration:
-```js
-"multiple": {
- "basic": {
- // run all tests in chrome and firefox
- "browsers": ["chrome", "firefox"]
- },
-
- "smoke": {
- "browsers": [
- "firefox",
- // replace any config values from WebDriver helper
- {
- "browser": "chrome",
- "windowSize": "maximize",
- "desiredCapabilities": {
- "acceptSslCerts": true
- }
- },
- ]
- },
-}
-```
-
-You can use `grep` and `outputName` params to filter tests and output directory for suite:
-```js
-"multiple": {
- "smoke": {
- // run only tests containing "@smoke" in name
- "grep": "@smoke",
-
- // store results into `output/smoke` directory
- "outputName": "smoke",
-
- "browsers": [
- "firefox",
- {"browser": "chrome", "windowSize": "maximize"}
- ]
- }
-}
-```
-
-Then tests can be executed using `run-multiple` command.
-
-Run all suites for all browsers:
-
-```sh
-codeceptjs run-multiple --all
-```
-
-Run `basic` suite for all browsers
-
-```sh
-codeceptjs run-multiple basic
-```
-
-Run `basic` suite for chrome only:
-
-```sh
-codeceptjs run-multiple basic:chrome
-```
-
-Run `basic` suite for chrome and `smoke` for firefox
-
-```sh
-codeceptjs run-multiple basic:chrome smoke:firefox
-```
-
-Run basic tests with grep and junit reporter
-
-```sh
-codeceptjs run-multiple basic --grep signin --reporter mocha-junit-reporter
-```
-
-Run regression tests specifying different config path:
-
-```sh
-codeceptjs run-multiple regression -c path/to/config
-```
-
-Each executed process uses custom folder for reports and output. It is stored in subfolder inside an output directory. Subfolders will be named in `suite_browser` format.
-
-Output is printed for all running processes. Each line is tagged with a suite and browser name:
-
-```sh
-[basic:firefox] GitHub --
-[basic:chrome] GitHub --
-[basic:chrome] it should not enter
-[basic:chrome] ✓ signin in 2869ms
-
-[basic:chrome] OK | 1 passed // 30s
-[basic:firefox] it should not enter
-[basic:firefox] ✖ signin in 2743ms
-
-[basic:firefox] -- FAILURES:
-```
-
-### Hooks
-
-Hooks are available when using the `run-multiple` command to perform actions before the test suites start and after the test suites have finished. See [Hooks](https://codecept.io/hooks/#bootstrap-teardown) for an example.
-
-
-## Parallel Execution
-
-CodeceptJS can be configured to run tests in parallel.
-
-When enabled, it collects all test files and executes them in parallel by the specified amount of chunks. Given we have five test scenarios (`a_test.js`,`b_test.js`,`c_test.js`,`d_test.js` and `e_test.js`), by setting `"chunks": 2` we tell the runner to run two suites in parallel. The first suite will run `a_test.js`,`b_test.js` and `c_test.js`, the second suite will run `d_test.js` and `e_test.js`.
-
-
-```js
-"multiple": {
- "parallel": {
- // Splits tests into 2 chunks
- "chunks": 2
- }
-}
-```
-
-To execute them use `run-multiple` command passing configured suite, which is `parallel` in this example:
-
-```
-codeceptjs run-multiple parallel
-```
-
-Grep and multiple browsers are supported. Passing more than one browser will multiply the amount of suites by the amount of browsers passed. The following example will lead to four parallel runs.
-
-```js
-"multiple": {
- // 2x chunks + 2x browsers = 4
- "parallel": {
- // Splits tests into chunks
- "chunks": 2,
- // run all tests in chrome and firefox
- "browsers": ["chrome", "firefox"]
- },
-}
-```
-
-Passing a function will enable you to provide your own chunking algorithm. The first argument passed to you function is an array of all test files, if you enabled grep the test files passed are already filtered to match the grep pattern.
-
-```js
-"multiple": {
- "parallel": {
- // Splits tests into chunks by passing an anonymous function,
- // only execute first and last found test file
- "chunks": (files) => {
- return [
- [ files[0] ], // chunk 1
- [ files[files.length-1] ], // chunk 2
- ]
- },
- // run all tests in chrome and firefox
- "browsers": ["chrome", "firefox"]
- }
-}
-```
-
-Note: Chunking will be most effective if you have many individual test files that contain only a small amount of scenarios. Otherwise the combined execution time of many scenarios or big scenarios in one single test file potentially lead to an uneven execution time.
-
## Test Options
Features and Scenarios have their options that can be set by passing a hash after their names:
@@ -386,5 +108,3 @@ Feature('Admin Panel').config({ url: 'https://mysite.com/admin' });
Please note that some config changes can't be applied on the fly. For instance, if you set `restart: false` in your config and then changing value `browser` won't take an effect as browser is already started and won't be closed untill all tests finish.
Configuration changes will be reverted after a test or a suite.
-
-## done()
diff --git a/docs/angular.md b/docs/angular.md
index 5c38a61f6..0efca18ba 100644
--- a/docs/angular.md
+++ b/docs/angular.md
@@ -110,7 +110,7 @@ codeceptjs gt
```
After that you can start writing your first CodeceptJS/Angular tests.
-Please look into the reference of [Protractor helper](http://codecept.io/helpers/Protractor/) for all available actions.
+Please look into the reference of [Protractor helper](helpers/Protractor.md) for all available actions.
You can also run `list` command to see methods of I:
```bash
@@ -297,6 +297,4 @@ element.all(by.repeater('result in memory'));
This way we recommend to implement all custom logic using low-level Protractor syntax and using it inside scenario tests.
Please see an [example of such helper](http://codecept.io/helpers/#protractor-example).
-### done()
-
-Almost ) This example is [available on GitHub](https://github.com/DavertMik/codeceptjs-angular-todomvc).
\ No newline at end of file
+This example is [available on GitHub](https://github.com/DavertMik/codeceptjs-angular-todomvc).
\ No newline at end of file
diff --git a/docs/api.md b/docs/api.md
new file mode 100644
index 000000000..dedbd9b2a
--- /dev/null
+++ b/docs/api.md
@@ -0,0 +1,322 @@
+
+# API
+
+**Use local CodeceptJS installation to get access to `codeceptjs` module**
+
+CodeceptJS provides an API which can be loaded via `require('codeceptjs')` when CodeceptJS is installed locally.
+These internal objects are available:
+
+* [`codecept`](https://github.com/Codeception/CodeceptJS/blob/master/lib/codecept.js): test runner class
+* [`config`](https://github.com/Codeception/CodeceptJS/blob/master/lib/config.js): current codecept config
+* [`event`](https://github.com/Codeception/CodeceptJS/blob/master/lib/event.js): event listener
+* [`recorder`](https://github.com/Codeception/CodeceptJS/blob/master/lib/recorder.js): global promise chain
+* [`output`](https://github.com/Codeception/CodeceptJS/blob/master/lib/output.js): internal printer
+* [`container`](https://github.com/Codeception/CodeceptJS/blob/master/lib/container.js): dependency injection container for tests, includes current helpers and support objects
+* [`helper`](https://github.com/Codeception/CodeceptJS/blob/master/lib/helper.js): basic helper class
+* [`actor`](https://github.com/Codeception/CodeceptJS/blob/master/lib/actor.js): basic actor (I) class
+
+[API reference](https://github.com/Codeception/CodeceptJS/tree/master/docs/api) is available on GitHub.
+Also please check the source code of corresponding modules.
+
+## Event Listeners
+
+CodeceptJS provides a module with [event dispatcher and set of predefined events](https://github.com/Codeception/CodeceptJS/blob/master/lib/event.js).
+
+It can be required from codeceptjs package if it is installed locally.
+
+```js
+const event = require('codeceptjs').event;
+
+module.exports = function() {
+
+ event.dispatcher.on(event.test.before, function (test) {
+
+ console.log('--- I am before test --');
+
+ });
+}
+```
+
+Available events:
+
+* `event.test.before(test)` - *async* when `Before` hooks from helpers and from test is executed
+* `event.test.after(test)` - *async* after each test
+* `event.test.started(test)` - *sync* at the very beginning of a test. Passes a current test object.
+* `event.test.passed(test)` - *sync* when test passed
+* `event.test.failed(test, error)` - *sync* when test failed
+* `event.test.finished(test)` - *sync* when test finished
+* `event.suite.before(suite)` - *async* before a suite
+* `event.suite.after(suite)` - *async* after a suite
+* `event.step.before(step)` - *async* when the step is scheduled for execution
+* `event.step.after(step)`- *async* after a step
+* `event.step.started(step)` - *sync* when step starts.
+* `event.step.passed(step)` - *sync* when step passed.
+* `event.step.failed(step, err)` - *sync* when step failed.
+* `event.step.finished(step)` - *sync* when step finishes.
+* `event.all.before` - before running tests
+* `event.all.after` - after running tests
+* `event.all.result` - when results are printed
+
+* *sync* - means that event is fired in the moment of action happens.
+* *async* - means that event is fired when an actions is scheduled. Use `recorder` to schedule your actions.
+
+For further reference look for [currently available listeners](https://github.com/Codeception/CodeceptJS/tree/master/lib/listener) using event system.
+
+### Test Object
+
+Test events provide a test object with following fields:
+
+* `title` title of a test
+* `body` test function as a string
+* `opts` additional test options like retries, and others
+* `pending` true if test is scheduled for execution and false if a test has finished
+* `tags` array of tags for this test
+* `file` path to a file with a test.
+* `steps` array of executed steps (available only in `test.passed`, `test.failed`, `test.finished` event)
+
+and others
+
+### Step Object
+
+Step events provide step objects with following fields:
+
+* `name` name of a step, like 'see', 'click', and others
+* `actor` current actor, in most cases it `I`
+* `helper` current helper instance used to execute this step
+* `helperMethod` corresponding helper method, in most cases is the same as `name`
+* `status` status of a step (passed or failed)
+* `prefix` if a step is executed inside `within` block contain within text, like: 'Within .js-signup-form'.
+* `args` passed arguments
+
+## Recorder
+
+To inject asynchronous functions in a test or before/after a test you can subscribe to corresponding event and register a function inside a recorder object. [Recorder](https://github.com/Codeception/CodeceptJS/blob/master/lib/recorder.js) represents a global promises chain.
+
+Provide a function description as a first parameter, function should return a promise:
+
+```js
+const event = require('codeceptjs').event;
+const recorder = require('codeceptjs').recorder;
+module.exports = function() {
+
+ event.dispatcher.on(event.test.before, function (test) {
+
+ const request = require('request');
+
+ recorder.add('create fixture data via API', function() {
+ return new Promise((doneFn, errFn) => {
+ request({
+ baseUrl: 'http://api.site.com/',
+ method: 'POST',
+ url: '/users',
+ json: { name: 'john', email: 'john@john.com' }
+ }), (err, httpResponse, body) => {
+ if (err) return errFn(err);
+ doneFn();
+ }
+ });
+ }
+ });
+}
+
+```
+
+Whenever you execute tests with `--verbose` option you will see registered events and promises executed by a recorder.
+
+
+## Output
+
+Output module provides 4 verbosity levels. Depending on the mode you can have different information printed using corresponding functions.
+
+* `default`: prints basic information using `output.print`
+* `steps`: toggled by `--steps` option, prints step execution
+* `debug`: toggled by `--debug` option, prints steps, and debug information with `output.debug`
+* `verbose`: toggled by `--verbose` prints debug information and internal logs with `output.log`
+
+It is recommended to avoid `console.log` and use output.* methods for printing.
+
+```js
+const output = require('codeceptjs').output;
+
+output.print('This is basic information');
+output.debug('This is debug information');
+output.log('This is verbose logging information');
+```
+
+## Container
+
+CodeceptJS has a dependency injection container with Helpers and Support objects.
+They can be retrieved from the container:
+
+```js
+let container = require('codeceptjs').container;
+
+// get object with all helpers
+let helpers = container.helpers();
+
+// get helper by name
+let WebDriver = container.helpers('WebDriver');
+
+// get support objects
+let support = container.support();
+
+// get support object by name
+let UserPage = container.support('UserPage');
+
+// get all registered plugins
+let plugins = container.plugins();
+```
+
+New objects can also be added to container in runtime:
+
+```js
+let container = require('codeceptjs').container;
+
+container.append({
+ helpers: { // add helper
+ MyHelper: new MyHelper({ config1: 'val1' });
+ },
+ support: { // add page object
+ UserPage: require('./pages/user');
+ }
+})
+```
+
+Container also contains current Mocha instance:
+
+```js
+let mocha = container.mocha();
+```
+
+## Config
+
+CodeceptJS config can be accessed from `require('codeceptjs').config.get()`:
+
+```js
+
+let config = require('codeceptjs').config.get();
+
+if (config.myKey == 'value') {
+ // run hook
+}
+```
+
+# Plugins
+
+Plugins allow to use CodeceptJS internal API to extend functionality. Use internal event dispatcher, container, output, promise recorder, to create your own reporters, test listeners, etc.
+
+CodeceptJS includes [built-in plugins](https://codecept.io/plugins/) which extend basic functionality and can be turned on and off on purpose. Taking them as [examples](https://github.com/Codeception/CodeceptJS/tree/master/lib/plugin) you can develop your custom plugins.
+
+A plugin is a basic JS module returning a function. Plugins can have individual configs which are passed into this function:
+
+```js
+const defaultConfig = {
+ someDefaultOption: true
+}
+
+module.exports = function(config) {
+ config = Object.assign(defaultConfig, config);
+ // do stuff
+}
+```
+
+Plugin can register event listeners or hook into promise chain with recorder. See [API reference](https://github.com/Codeception/CodeceptJS/tree/master/lib/helper).
+
+To enable your custom plugin in config add it to `plugins` section. Specify path to node module using `require`.
+
+```js
+"plugins": {
+ "myPlugin": {
+ "require": "./path/to/my/module",
+ "enabled": true
+ }
+}
+```
+
+* `require` - specifies relative path to a plugin file. Path is relative to config file.
+* `enabled` - to enable this plugin.
+
+If a plugin is disabled (`enabled` is not set or false) this plugin can be enabled from command line:
+
+```
+./node_modules/.bin/codeceptjs run --plugin myPlugin
+```
+
+Several plugins can be enabled as well:
+
+```
+./node_modules/.bin/codeceptjs run --plugin myPlugin,allure
+```
+
+## Example: Execute code for a specific group of tests
+
+If you need to execute some code before a group of tests, you can [mark these tests with a same tag](https://codecept.io/advanced/#tags). Then to listen for tests where this tag is included (see [test object api](#test-object)).
+
+Let's say we need to populate database for a group of tests.
+
+```js
+// populate database for slow tests
+const event = require('codeceptjs').event;
+
+module.exports = function() {
+
+ event.dispatcher.on(event.test.before, function (test) {
+
+ if (test.tags.indexOf('@populate') >= 0) {
+ recorder.add('populate database', async () => {
+ // populate database for this test
+ })
+ }
+ });
+}
+```
+
+# Custom Hooks
+
+*(deprecated, use [plugins](#plugins))*
+
+Hooks are JavaScript files same as for bootstrap and teardown, which can be registered inside `hooks` section of config. Unlike `bootstrap` you can have multiple hooks registered:
+
+```json
+"hooks": [
+ "./server.js",
+ "./data_builder.js",
+ "./report_notification.js"
+]
+```
+
+Inside those JS files you can use CodeceptJS API (see below) to access its internals.
+
+
+# Custom Runner
+
+CodeceptJS can be imported and used in custom runners.
+To initialize Codecept you need to create Config and Container objects.
+
+```js
+let Container = require('codeceptjs').container;
+let Codecept = require('codeceptjs').codecept;
+
+let config = { helpers: { WebDriver: { browser: 'chrome', url: 'http://localhost' } } };
+let opts = { steps: true };
+
+// create runner
+let codecept = new Codecept(config, opts);
+
+// initialize codeceptjs in current dir
+codecept.initGlobals(__dirname);
+
+// create helpers, support files, mocha
+Container.create(config, opts);
+
+// initialize listeners
+codecept.bootstrap();
+
+// load tests
+codecept.loadTests('*_test.js');
+
+// run tests
+codecept.run();
+```
+
+In this way Codecept runner class can be extended.
diff --git a/docs/basics.md b/docs/basics.md
index 884c0901e..0012f1bc5 100644
--- a/docs/basics.md
+++ b/docs/basics.md
@@ -22,7 +22,7 @@ CodeceptJS bypasses execution commands to helpers. Depending on helper enabled y
Here is the diagram of CodeceptJS architecture
-
+
All helpers share the same API so it's easy to migrate tests from one backend to other.
However, because of difference in backends and their limitations, they are not guarantted to compatible between each other. For instance, you can't set request headers in WebDriver or Protractor, but you can do so in Puppteer or Nigthmare.
@@ -133,143 +133,6 @@ It is recommended to [filter tests by tags](https://codecept.io/advanced/#tags).
> For more options see [full reference of `run` command](https://codecept.io/commands/#run).
-## Debug
-
-CodeceptJS allows to write and debug tests on the fly while keeping your browser opened.
-By using interactive shell you can stop execution at any point and type in CodeceptJS commands.
-
-This is especially useful while writing a new scratch. After opening a page call `pause()` to start interacting with a page:
-
-```js
-I.amOnPage('/');
-pause();
-```
-
-Try to perform your scenario step by step. Then copy succesful commands and insert them into a test.
-
-### Pause
-
-Test execution can be paused in any place of a test with `pause()` call.
-
-This launches interactive console where you can call actions of `I` object.
-
-```
- Interactive shell started
- Press ENTER to resume test
- - Use JavaScript syntax to try steps in action
- - Press TAB twice to see all available commands
- - Enter next to run the next step
- I.click
-
-```
-
-Type in different actions to try them, copy valid successful ones to test, update the test file.
-
-Press `ENTER` to resume test execution.
-
-To **debug test step-by-step** type `next` and press Enter. The next step will be executed and interactive shell will be shown again.
-
-To see all available commands press TAB two times to see list of all actions included in I.
-
-If a test is failing you can prevent browser from closing by putting `pause()` command into `After()` hook. This is very helpful to debug failing tests. This way you can keep the same session and try different actions on a page to get the idea what went wrong.
-
-```js
-After(pause);
-```
-
-Interactive shell can be started outside the test context by running
-
-```bash
-codeceptjs shell
-```
-
-
-### Screenshot on failure
-
-By default CodeceptJS saves a screenshot of a failed test.
-This can be configured in [screenshotOnFail Plugin](https://codecept.io/plugins/#screenshotonfail)
-
-### Step By Step Report
-
-To see how the test was executed, use [stepByStepReport Plugin](https://codecept.io/plugins/#stepbystepreport). It saves a screenshot of each passed step and shows them in a nice slideshow.
-
-
-## Before
-
-Common preparation steps like opening a web page, logging in a user, can be placed in `Before` or `Background` hook:
-
-```js
-Feature('CodeceptJS Demonstration');
-
-Before((I) => { // or Background
- I.amOnPage('/documentation');
-});
-
-Scenario('test some forms', (I) => {
- I.click('Create User');
- I.see('User is valid');
- I.dontSeeInCurrentUrl('/documentation');
-});
-
-Scenario('test title', (I) => {
- I.seeInTitle('Example application');
-});
-```
-
-Same as `Before` you can use `After` to run teardown for each scenario.
-
-## BeforeSuite
-
-If you need to run complex setup before all tests and teardown this afterwards you can use `BeforeSuite` and `AfterSuite`
-functions. `BeforeSuite` and `AfterSuite` have access to `I` object, but `BeforeSuite/AfterSuite` don't have an access to the browser because it's not running at this moment.
-You can use them to execute handlers that will setup your environment. `BeforeSuite/AfterSuite` will work only for a file where it was declared (so you can declare different setups for files)
-
-```js
-BeforeSuite((I) => {
- I.syncDown('testfolder');
-});
-
-AfterSuite((I) => {
- I.syncUp('testfolder');
- I.clearDir('testfolder');
-});
-```
-
-[Here are some ideas](https://github.com/Codeception/CodeceptJS/pull/231#issuecomment-249554933) where to use BeforeSuite hooks.
-
-## Within
-
-To specify the exact area on a page where actions can be performed you can use `within` function.
-Everything executed in its context will be narrowed to context specified by locator:
-
-Usage: `within('section', ()=>{})`
-
-```js
-I.amOnPage('https://github.com');
-within('.js-signup-form', () => {
- I.fillField('user[login]', 'User');
- I.fillField('user[email]', 'user@user.com');
- I.fillField('user[password]', 'user@user.com');
- I.click('button');
-});
-I.see('There were problems creating your account.');
-```
-
-`within` can also work with [iframes](/acceptance/#iframes)
-
-When running steps inside a within block will be shown with a shift:
-
-
-
-Within can return a value which can be used in a scenario:
-
-```js
-// inside async function
-const val = await within('#sidebar', () => {
- return I.grabTextFrom({ css: 'h1' });
-});
-I.fillField('Description', val);
-```
## Comments
@@ -302,84 +165,10 @@ codeceptjs def
Now you should include `/// ` into your test files to get
method autocompletion while writing tests.
-## Skipping
-
-Like in Mocha you can use `x` and `only` to skip tests or making a single test to run.
-
-* `xScenario` - skips current test
-* `Scenario.only` - executes only the current test
-
-
-## Retries
-
-### Retry Step
-
-If you have a step which often fails you can retry execution for this single step.
-Use `retry()` function before an action to ask CodeceptJS to retry this step on failure:
-
-```js
-I.retry().see('Welcome');
-```
-
-If you'd like to retry step more than once pass the amount as parameter:
-
-```js
-I.retry(3).see('Welcome');
-```
-
-Additional options can be provided to retry so you can set the additional options (defined in [promise-retry](https://www.npmjs.com/package/promise-retry) library).
-
-
-```js
-// retry action 3 times waiting for 0.1 second before next try
-I.retry({ retries: 3, minTimeout: 100 }).see('Hello');
-
-// retry action 3 times waiting no more than 3 seconds for last retry
-I.retry({ retries: 3, maxTimeout: 3000 }).see('Hello');
-
-// retry 2 times if error with message 'Node not visible' happens
-I.retry({
- retries: 2,
- when: err => err.message === 'Node not visible'
-}).seeElement('#user');
-```
-
-Pass a function to `when` option to retry only when error matches the expected one.
-
-### Auto Retry
-
-You can auto-retry a failed step by enabling [retryFailedStep Plugin](https://codecept.io/plugins/#retryfailedstep).
-
-### Retry Scenario
-When you need to rerun scenarios few times just add `retries` option added to `Scenario` declaration.
-CodeceptJS implements retries the same way [Mocha do](https://mochajs.org#retry-tests);
-You can set number of a retries for a feature:
-
-```js
-Scenario('Really complex', (I) => {
- // test goes here
-}).retry(2);
-
-// alternative
-Scenario('Really complex', { retries: 2 }, (I) => {});
-```
-
-This scenario will be restarted two times on a failure.
-
-### Retry Feature
-
-To set this option for all scenarios in a file, add retry to a feature:
-
-```js
-Feature('Complex JS Stuff').retry(3);
-```
-
-Every Scenario inside this feature will be rerun 3 times.
-You can make an exception for a specific scenario by passing `retries` option to a Scenario.
+---
+### Next: [Acceptance Testing >>>](acceptance.md)
---
-
-### done()
diff --git a/docs/bdd.md b/docs/bdd.md
index e744e41b7..677852bfa 100644
--- a/docs/bdd.md
+++ b/docs/bdd.md
@@ -339,4 +339,8 @@ To run only tests without features use `--tests` option:
codeceptjs run --tests
```
-## done()
+---
+
+### Next: [Test Lifecycle >>>](lifecycle.md)
+
+---
\ No newline at end of file
diff --git a/docs/data.md b/docs/data.md
index 8f8e7f601..357a99f36 100644
--- a/docs/data.md
+++ b/docs/data.md
@@ -1,6 +1,6 @@
# Data Management
-*This chapter describes data management for external sources. If you are looking for using Data Sets in tests, see [Data Driven Tests](http://codecept.io/advanced/#data-drivern-tests) section*
+*This chapter describes data management for external sources. If you are looking for using Data Sets in tests, see [Data Driven Tests](datadriven.md) concept*
Managing data for tests is always a tricky issue. How isolate data between tests, how to prepare data for different tests, etc.
There are different approaches to solve it:
@@ -17,13 +17,13 @@ API supposed to be a stable interface and it can be used by acceptance tests. Co
## REST
-[REST helper](http://codecept.io/helpers/REST/) uses [Unirest](http://unirest.io/nodejs.html) library to send HTTP requests to application.
+[REST helper](helpers/REST.md) uses [Axios](https://github.com/axios/axios) library to send HTTP requests to application.
However, it doesn't provide tools for testing APIs, so it should be paired with WebDriver, Nightmare or Protractor helpers for browser testing.
Enable REST helper in global config. It is recommended to set `endpoint`, a base URL for all API requests.
If you need some authorization you can optionally set default headers too.
-See the sample config:
+See this sample config:
```js
"helpers": {
@@ -40,7 +40,9 @@ See the sample config:
}
```
-REST helper provides basic methods to send requests to application:
+Note that the `WebDriver` helper is still there, and it is handling all the web-page related commands like `I.click` and so on.
+
+The `REST` helper provides basic methods to send requests to application:
```js
I.sendGetRequest()
@@ -52,7 +54,7 @@ I.sendDeleteRequest()
As well as a method for setting headers: `haveRequestHeaders`.
-Here is a usage example:
+Here is an example:
```js
let postId = null;
@@ -83,7 +85,7 @@ I.sendPostRequest('/update-status', {}, { http_x_requested_with: 'xmlhttprequest
## Data Generation with Factories
-This concept is extended by [ApiDataFactory](http://codecept.io/helpers/ApiDataFactory/) helper.
+This concept is extended by [ApiDataFactory](helpers/ApiDataFactory.md) helper.
It builds data according to defined rules and uses API to store them and automatically clean them up after a test,
This way setting data for a test is as simple as writing:
@@ -139,6 +141,4 @@ At the end of a test ApiDataFactory will clean up created record for you. This i
ids from crated records and running `DELETE /api/users/{id}` requests at the end of a test.
This rules can be customized in helper configuration.
----
-### done()
diff --git a/docs/datadriven.md b/docs/datadriven.md
new file mode 100644
index 000000000..7e5fa2854
--- /dev/null
+++ b/docs/datadriven.md
@@ -0,0 +1,76 @@
+
+# Data Driven Tests
+
+Execute the same scenario on a different data set.
+
+Let's say you want to test login for different user accounts.
+In this case, you need to create a datatable and fill it in with credentials.
+Then use `Data().Scenario` to include this data and generate multiple scenarios:
+
+```js
+// Define data table inside a test or load from another module
+let accounts = new DataTable(['login', 'password']); //
+accounts.add(['davert', '123456']); // adding records to a table
+accounts.add(['admin', '123456']);
+
+// You can skip some data. But add them to report as skipped (just like with usual scenarios):
+accounts.xadd(['admin', '23456'])
+
+// Pass dataTable to Data()
+// Use special param `current` to get current data set
+Data(accounts).Scenario('Test Login', (I, current) => {
+ I.fillField('Username', current.login); // current is reserved!
+ I.fillField('Password', current.password);
+ I.click('Sign In');
+ I.see('Welcome '+ current.login);
+});
+
+
+// Also you can set only for Data tests. It will launch executes only the current test but with all data options
+Data(accounts).only.Scenario('Test Login', (I, current) => {
+ I.fillField('Username', current.login); // current is reserved!
+ I.fillField('Password', current.password);
+ I.click('Sign In');
+ I.see('Welcome '+ current.login);
+});
+```
+
+*Important: you can't use name `current` for pageObjects or helpers in data scenarios*
+
+This will produce 2 tests with different data sets.
+Current data set is appended to a test name in output:
+
+```sh
+✓ Test Login | {"login":"davert","password":"123456"}
+✓ Test Login | {"login":"admin","password":"123456"}
+S Test Login | {"login":"admin","password":"23456"}
+```
+
+```js
+// You can filter your data table
+Data(accounts.filter(account => account.login == 'admin')
+.Scenario('Test Login', (I, current) => {
+ I.fillField('Username', current.login);
+ I.fillField('Password', current.password);
+ I.click('Sign In');
+ I.see('Welcome '+ current.login);
+});
+```
+
+This will limit data sets accoring passed function:
+
+```sh
+✓ Test Login | {"login":"admin","password":"123456"}
+S Test Login | {"login":"admin","password":"23456"}
+```
+
+Data sets can also be defined with array, generator, or a function.
+
+```js
+Data(function*() {
+ yield { user: 'davert'};
+ yield { user: 'andrey'};
+}).Scenario() // ...
+```
+
+*HINT: If you don't use DataTable. add `toString()` method to each object added to data set, so the data could be pretty printed in a test name*
diff --git a/docs/debugging.md b/docs/debugging.md
new file mode 100644
index 000000000..543235904
--- /dev/null
+++ b/docs/debugging.md
@@ -0,0 +1,127 @@
+# Debug
+
+CodeceptJS allows to write and debug tests on the fly while keeping your browser opened.
+By using interactive shell you can stop execution at any point and type in CodeceptJS commands.
+
+This is especially useful while writing a new scratch. After opening a page call `pause()` to start interacting with a page:
+
+```js
+I.amOnPage('/');
+pause();
+```
+
+Try to perform your scenario step by step. Then copy succesful commands and insert them into a test.
+
+## Pause
+
+Test execution can be paused in any place of a test with `pause()` call.
+
+This launches interactive console where you can call actions of `I` object.
+
+```
+ Interactive shell started
+ Press ENTER to resume test
+ - Use JavaScript syntax to try steps in action
+ - Press TAB twice to see all available commands
+ - Enter next to run the next step
+ I.click
+
+```
+
+Type in different actions to try them, copy valid successful ones to test, update the test file.
+
+Press `ENTER` to resume test execution.
+
+To **debug test step-by-step** type `next` and press Enter. The next step will be executed and interactive shell will be shown again.
+
+To see all available commands press TAB two times to see list of all actions included in I.
+
+If a test is failing you can prevent browser from closing by putting `pause()` command into `After()` hook. This is very helpful to debug failing tests. This way you can keep the same session and try different actions on a page to get the idea what went wrong.
+
+```js
+After(pause);
+```
+
+Interactive shell can be started outside the test context by running
+
+```bash
+codeceptjs shell
+```
+
+
+## Screenshot on failure
+
+By default CodeceptJS saves a screenshot of a failed test.
+This can be configured in [screenshotOnFail Plugin](https://codecept.io/plugins/#screenshotonfail)
+
+## Step By Step Report
+
+To see how the test was executed, use [stepByStepReport Plugin](https://codecept.io/plugins/#stepbystepreport). It saves a screenshot of each passed step and shows them in a nice slideshow.
+
+
+# Debug Mode
+
+CodeceptJS provides a debug mode in which additional information is printed.
+It can be turned on with `--debug` flag.
+
+```sh
+codeceptjs run --debug
+```
+
+to receive even more information turn on `--verbose` flag:
+
+```sh
+codeceptjs run --verbose
+```
+
+And don't forget that you can pause execution and enter **interactive console** mode by calling `pause()` inside your test.
+
+## Attach Debugger
+
+For advanced debugging use NodeJS debugger. In **WebStorm IDE**:
+
+```sh
+node $NODE_DEBUG_OPTION ./node_modules/.bin/codeceptjs run
+```
+
+For **Visual Studio Code**, add the following configuration in launch.json:
+
+```json
+{
+ "type": "node",
+ "request": "launch",
+ "name": "codeceptjs",
+ "args": ["run", "--grep", "@your_test_tag"],
+ "program": "${workspaceFolder}/node_modules/.bin/codeceptjs"
+}
+```
+This will let you set breakpoints inside your tests.
+
+```js
+Scenario('test', (I) => {
+ I.amOnPage('/');
+ I.click('Login');
+ I.see('Please Login', 'h1');
+ // ...
+});
+```
+
+You will be disappointed first time you try. The actor functions in CodeceptJS (like `I.click('Login')`) are asynchronous. They add actions to a promise chain but do not wait for the action to complete. You can step,step,step and nothing happens in the browser.
+
+The easy way to solve this is to add `await` for all actor calls. This forces the test to wait for the promise chain to finish.
+
+```js
+Scenario('test', async (I) => {
+ await I.amOnPage('/');
+ await I.click('Login');
+ await I.see('Please Login', 'h1');
+ // ...
+});
+```
+
+
+---
+
+### Next: [Helpers >>>](helpers.md)
+
+---
\ No newline at end of file
diff --git a/docs/drag-drop.md b/docs/drag-drop.md
new file mode 100644
index 000000000..832d59e39
--- /dev/null
+++ b/docs/drag-drop.md
@@ -0,0 +1,44 @@
+# Drag and Drop
+
+There is no browser support for drag-and-drop, so every page builds its own version.
+
+Most of the Codecept helpers do support a `dragAndDrop` command, but whether it will work for your implementation of dragging varies.
+
+### dragAndDrop
+
+Drag an item to a destination element.
+
+```js
+I.dragAndDrop('#dragHandle', '#container');
+```
+
+#### Parameters
+
+- `srcElement` located by CSS|XPath|strict locator.
+- `destElement` located by CSS|XPath|strict locator.
+
+## JQueryUI Drag+Drop Example
+
+Using http://jqueryui.com/resources/demos/droppable/default.html
+
+```js
+// Drag item from source to target (no iframe) @dragNdrop',
+I.amOnPage('http://jqueryui.com/resources/demos/droppable/default.html')
+I.seeElementInDOM('#draggable')
+I.dragAndDrop('#draggable', '#droppable')
+I.see('Dropped');
+```
+
+## JQuery Drag+Drop within iframe
+
+Using http://jqueryui.com/droppable
+
+```js
+// Drag and drop from within an iframe
+I.amOnPage('http://jqueryui.com/droppable')
+I.resizeWindow(700, 700)
+I.switchTo('//iframe[@class="demo-frame"]')
+I.seeElementInDOM('#draggable')
+I.dragAndDrop('#draggable', '#droppable')
+I.see('Dropped');
+```
diff --git a/docs/frames.md b/docs/frames.md
new file mode 100644
index 000000000..2c07544b9
--- /dev/null
+++ b/docs/frames.md
@@ -0,0 +1,36 @@
+# Within frames and iframes
+
+Codecept supports working within multiple frames on a page using the `within` function.
+
+Note that waits for the iframe page follow the same model as page-to-page navigation, and if your frame takes too long to load, it may break your test.
+
+## IFrames
+
+The [within](locators.md#within) operator can be used to work inside IFrames. Special `frame` locator is required to locate the iframe and get into its context.
+
+For example:
+
+```js
+within({frame: "#editor"}, () => {
+ I.see('Page');
+});
+```
+
+Nested IFrames can be set by passing array *(WebDriver, Nightmare & Puppeteer only)*:
+
+```js
+within({frame: [".content", "#editor"]}, () => {
+ I.see('Page');
+});
+```
+
+Please take a note that you can't use within inside another within in Puppeteer helper:
+
+```js
+within('.todoapp', () => {
+ I.createTodo('my new item');
+ I.see('1 item left', '.todo-count');
+ I.click('.todo-list input.toggle');
+});
+I.see('0 items left', '.todo-count');
+```
diff --git a/docs/helpers.md b/docs/helpers.md
index 8d6c9775e..817e80b47 100644
--- a/docs/helpers.md
+++ b/docs/helpers.md
@@ -253,4 +253,3 @@ _before() {
Retry rules are available in array `recorder.retries`. The last retry rule can be disabled by running `recorder.retries.pop()`;
-### done()
diff --git a/docs/hooks.md b/docs/hooks.md
index cbb58e141..8087c2e72 100644
--- a/docs/hooks.md
+++ b/docs/hooks.md
@@ -18,7 +18,9 @@ There are different ways to define bootstrap and teardown functions:
Corresponding examples provided in next sections.
-### Example: Async Bootstrap in a Function
+## Examples
+
+### Async Bootstrap in a Function
Add to `codecept.conf.js`:
@@ -167,327 +169,3 @@ exports.config = {
**Note**: The `bootstrapAll` and `teardownAll` hooks are only called when using [Multiple Execution](http://codecept.io/advanced/#multiple-execution).
-
-## API
-
-**Use local CodeceptJS installation to get access to `codeceptjs` module**
-
-CodeceptJS provides an API which can be loaded via `require('codeceptjs')` when CodeceptJS is installed locally.
-These internal objects are available:
-
-* [`codecept`](https://github.com/Codeception/CodeceptJS/blob/master/lib/codecept.js): test runner class
-* [`config`](https://github.com/Codeception/CodeceptJS/blob/master/lib/config.js): current codecept config
-* [`event`](https://github.com/Codeception/CodeceptJS/blob/master/lib/event.js): event listener
-* [`recorder`](https://github.com/Codeception/CodeceptJS/blob/master/lib/recorder.js): global promise chain
-* [`output`](https://github.com/Codeception/CodeceptJS/blob/master/lib/output.js): internal printer
-* [`container`](https://github.com/Codeception/CodeceptJS/blob/master/lib/container.js): dependency injection container for tests, includes current helpers and support objects
-* [`helper`](https://github.com/Codeception/CodeceptJS/blob/master/lib/helper.js): basic helper class
-* [`actor`](https://github.com/Codeception/CodeceptJS/blob/master/lib/actor.js): basic actor (I) class
-
-[API reference](https://github.com/Codeception/CodeceptJS/tree/master/docs/api) is available on GitHub.
-Also please check the source code of corresponding modules.
-
-### Event Listeners
-
-CodeceptJS provides a module with [event dispatcher and set of predefined events](https://github.com/Codeception/CodeceptJS/blob/master/lib/event.js).
-
-It can be required from codeceptjs package if it is installed locally.
-
-```js
-const event = require('codeceptjs').event;
-
-module.exports = function() {
-
- event.dispatcher.on(event.test.before, function (test) {
-
- console.log('--- I am before test --');
-
- });
-}
-```
-
-Available events:
-
-* `event.test.before(test)` - *async* when `Before` hooks from helpers and from test is executed
-* `event.test.after(test)` - *async* after each test
-* `event.test.started(test)` - *sync* at the very beginning of a test. Passes a current test object.
-* `event.test.passed(test)` - *sync* when test passed
-* `event.test.failed(test, error)` - *sync* when test failed
-* `event.test.finished(test)` - *sync* when test finished
-* `event.suite.before(suite)` - *async* before a suite
-* `event.suite.after(suite)` - *async* after a suite
-* `event.step.before(step)` - *async* when the step is scheduled for execution
-* `event.step.after(step)`- *async* after a step
-* `event.step.started(step)` - *sync* when step starts.
-* `event.step.passed(step)` - *sync* when step passed.
-* `event.step.failed(step, err)` - *sync* when step failed.
-* `event.step.finished(step)` - *sync* when step finishes.
-* `event.all.before` - before running tests
-* `event.all.after` - after running tests
-* `event.all.result` - when results are printed
-
-* *sync* - means that event is fired in the moment of action happens.
-* *async* - means that event is fired when an actions is scheduled. Use `recorder` to schedule your actions.
-
-For further reference look for [currently available listeners](https://github.com/Codeception/CodeceptJS/tree/master/lib/listener) using event system.
-
-#### Test Object
-
-Test events provide a test object with following fields:
-
-* `title` title of a test
-* `body` test function as a string
-* `opts` additional test options like retries, and others
-* `pending` true if test is scheduled for execution and false if a test has finished
-* `tags` array of tags for this test
-* `file` path to a file with a test.
-* `steps` array of executed steps (available only in `test.passed`, `test.failed`, `test.finished` event)
-
-and others
-
-#### Step Object
-
-Step events provide step objects with following fields:
-
-* `name` name of a step, like 'see', 'click', and others
-* `actor` current actor, in most cases it `I`
-* `helper` current helper instance used to execute this step
-* `helperMethod` corresponding helper method, in most cases is the same as `name`
-* `status` status of a step (passed or failed)
-* `prefix` if a step is executed inside `within` block contain within text, like: 'Within .js-signup-form'.
-* `args` passed arguments
-
-### Recorder
-
-To inject asynchronous functions in a test or before/after a test you can subscribe to corresponding event and register a function inside a recorder object. [Recorder](https://github.com/Codeception/CodeceptJS/blob/master/lib/recorder.js) represents a global promises chain.
-
-Provide a function description as a first parameter, function should return a promise:
-
-```js
-const event = require('codeceptjs').event;
-const recorder = require('codeceptjs').recorder;
-module.exports = function() {
-
- event.dispatcher.on(event.test.before, function (test) {
-
- const request = require('request');
-
- recorder.add('create fixture data via API', function() {
- return new Promise((doneFn, errFn) => {
- request({
- baseUrl: 'http://api.site.com/',
- method: 'POST',
- url: '/users',
- json: { name: 'john', email: 'john@john.com' }
- }), (err, httpResponse, body) => {
- if (err) return errFn(err);
- doneFn();
- }
- });
- }
- });
-}
-
-```
-
-Whenever you execute tests with `--verbose` option you will see registered events and promises executed by a recorder.
-
-
-### Output
-
-Output module provides 4 verbosity levels. Depending on the mode you can have different information printed using corresponding functions.
-
-* `default`: prints basic information using `output.print`
-* `steps`: toggled by `--steps` option, prints step execution
-* `debug`: toggled by `--debug` option, prints steps, and debug information with `output.debug`
-* `verbose`: toggled by `--verbose` prints debug information and internal logs with `output.log`
-
-It is recommended to avoid `console.log` and use output.* methods for printing.
-
-```js
-const output = require('codeceptjs').output;
-
-output.print('This is basic information');
-output.debug('This is debug information');
-output.log('This is verbose logging information');
-```
-
-### Container
-
-CodeceptJS has a dependency injection container with Helpers and Support objects.
-They can be retrieved from the container:
-
-```js
-let container = require('codeceptjs').container;
-
-// get object with all helpers
-let helpers = container.helpers();
-
-// get helper by name
-let WebDriver = container.helpers('WebDriver');
-
-// get support objects
-let support = container.support();
-
-// get support object by name
-let UserPage = container.support('UserPage');
-
-// get all registered plugins
-let plugins = container.plugins();
-```
-
-New objects can also be added to container in runtime:
-
-```js
-let container = require('codeceptjs').container;
-
-container.append({
- helpers: { // add helper
- MyHelper: new MyHelper({ config1: 'val1' });
- },
- support: { // add page object
- UserPage: require('./pages/user');
- }
-})
-```
-
-Container also contains current Mocha instance:
-
-```js
-let mocha = container.mocha();
-```
-
-### Config
-
-CodeceptJS config can be accessed from `require('codeceptjs').config.get()`:
-
-```js
-
-let config = require('codeceptjs').config.get();
-
-if (config.myKey == 'value') {
- // run hook
-}
-```
-
-## Plugins
-
-Plugins allow to use CodeceptJS internal API to extend functionality. Use internal event dispatcher, container, output, promise recorder, to create your own reporters, test listeners, etc.
-
-CodeceptJS includes [built-in plugins](https://codecept.io/plugins/) which extend basic functionality and can be turned on and off on purpose. Taking them as [examples](https://github.com/Codeception/CodeceptJS/tree/master/lib/plugin) you can develop your custom plugins.
-
-A plugin is a basic JS module returning a function. Plugins can have individual configs which are passed into this function:
-
-```js
-const defaultConfig = {
- someDefaultOption: true
-}
-
-module.exports = function(config) {
- config = Object.assign(defaultConfig, config);
- // do stuff
-}
-```
-
-Plugin can register event listeners or hook into promise chain with recorder. See [API reference](https://github.com/Codeception/CodeceptJS/tree/master/lib/helper).
-
-To enable your custom plugin in config add it to `plugins` section. Specify path to node module using `require`.
-
-```js
-"plugins": {
- "myPlugin": {
- "require": "./path/to/my/module",
- "enabled": true
- }
-}
-```
-
-* `require` - specifies relative path to a plugin file. Path is relative to config file.
-* `enabled` - to enable this plugin.
-
-If a plugin is disabled (`enabled` is not set or false) this plugin can be enabled from command line:
-
-```
-./node_modules/.bin/codeceptjs run --plugin myPlugin
-```
-
-Several plugins can be enabled as well:
-
-```
-./node_modules/.bin/codeceptjs run --plugin myPlugin,allure
-```
-
-### Example: Execute code for a specific group of tests
-
-If you need to execute some code before a group of tests, you can [mark these tests with a same tag](https://codecept.io/advanced/#tags). Then to listen for tests where this tag is included (see [test object api](#test-object)).
-
-Let's say we need to populate database for a group of tests.
-
-```js
-// populate database for slow tests
-const event = require('codeceptjs').event;
-
-module.exports = function() {
-
- event.dispatcher.on(event.test.before, function (test) {
-
- if (test.tags.indexOf('@populate') >= 0) {
- recorder.add('populate database', async () => {
- // populate database for this test
- })
- }
- });
-}
-```
-
-## Custom Hooks
-
-*(deprecated, use [plugins](#plugins))*
-
-Hooks are JavaScript files same as for bootstrap and teardown, which can be registered inside `hooks` section of config. Unlike `bootstrap` you can have multiple hooks registered:
-
-```json
-"hooks": [
- "./server.js",
- "./data_builder.js",
- "./report_notification.js"
-]
-```
-
-Inside those JS files you can use CodeceptJS API (see below) to access its internals.
-
-
-## Custom Runner
-
-CodeceptJS can be imported and used in custom runners.
-To initialize Codecept you need to create Config and Container objects.
-
-```js
-let Container = require('codeceptjs').container;
-let Codecept = require('codeceptjs').codecept;
-
-let config = { helpers: { WebDriver: { browser: 'chrome', url: 'http://localhost' } } };
-let opts = { steps: true };
-
-// create runner
-let codecept = new Codecept(config, opts);
-
-// initialize codeceptjs in current dir
-codecept.initGlobals(__dirname);
-
-// create helpers, support files, mocha
-Container.create(config, opts);
-
-// initialize listeners
-codecept.bootstrap();
-
-// load tests
-codecept.loadTests('*_test.js');
-
-// run tests
-codecept.run();
-```
-
-In this way Codecept runner class can be extended.
-
-## done()
diff --git a/docs/installation.md b/docs/installation.md
index d52554145..16e8421fb 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -1,41 +1,49 @@
# Installation
-## Local
+## Global Installation
-Use NPM install CodeceptJS:
+CodeceptJS can be installed together with a suitable driver via NPM globally:
```sh
-npm install --save-dev codeceptjs
+[sudo] npm install -g codeceptjs webdriverio
+# or
+[sudo] npm install -g codeceptjs protractor
+# or
+[sudo] npm install -g codeceptjs puppeteer
+# or
+[sudo] npm install -g codeceptjs nightmare
```
-and started as
+then it can be started anywhere using
```sh
-./node_modules/.bin/codeceptjs
+codeceptjs
```
-To use it with WebDriver install webdriverio package:
+Global installations are easier to use on the command-line, but are not registered in the `package.json` manifest for your project, so they won't be automatically installed for others who download your source code. It also means you need to install these tools on the CI/Build servers before you can run the tests there.
-```sh
-npm install webdriverio --save-dev
-```
+## Local Installation
-To use it with Protractor install protractor package:
+Use NPM install CodeceptJS:
```sh
-npm install protractor --save-dev
+npm install --save-dev codeceptjs
```
-To use it with Nightmare install nightmare and nightmare-upload packages:
-
```sh
-npm install nightmare --save-dev
+npm install --save-dev codeceptjs webdriver
+# or
+npm install --save-dev codeceptjs protractor
+# or
+npm install --save-dev codeceptjs puppeteer
+# or
+npm install --save-dev codeceptjs nightmare
```
-To use it with Puppeteer install puppeteer package:
+and started as
```sh
-npm install puppeteer --save-dev
+./node_modules/.bin/codeceptjs
```
## WebDriver
@@ -45,9 +53,14 @@ WebDriver based helpers like WebDriver, Protractor, Selenium WebDriver will requ
We recommend to install them manually or use NPM packages:
* [Selenium Standalone](https://www.npmjs.com/package/selenium-standalone) to install and run Selenium, ChromeDriver, Firefox Driver with one package.
+ ```sh
+ npm install selenium-standalone --save-dev
+ ```
+ Selenium is [Java](https://www.java.com/en/download/) based, so you may need to install or update that first.
+
* [Phantomjs](https://www.npmjs.com/package/phantomjs-prebuilt): to install and execute Phantomjs
-or use [Docker](https://github.com/SeleniumHQ/docker-selenium) for headless browser testing.
+or use [Docker with Selenium](https://github.com/SeleniumHQ/docker-selenium) for headless browser testing in a container.
Launch Selenium with Chrome browser inside a Docker container:
@@ -55,22 +68,3 @@ Launch Selenium with Chrome browser inside a Docker container:
docker run --net=host selenium/standalone-chrome
```
-## Global
-
-CodeceptJS can be installed via NPM globally:
-
-```sh
-[sudo] npm install -g codeceptjs webdriverio
-# or
-[sudo] npm install -g codeceptjs protractor
-# or
-[sudo] npm install -g codeceptjs puppeteer
-# or
-[sudo] npm install -g codeceptjs nightmare
-```
-
-then it can be started as
-
-```sh
-codeceptjs
-```
diff --git a/docs/lifecycle.md b/docs/lifecycle.md
new file mode 100644
index 000000000..07bab14c4
--- /dev/null
+++ b/docs/lifecycle.md
@@ -0,0 +1,153 @@
+# Test Lifecycle
+
+CodeceptJS running-a-test lifecycle
+
+1. Run `BeforeSuite()` function
+2. Start browser for test
+3. Run `Before()` function to set up test
+4. Run the test
+5. Run the `After()` function to clean up
+6. Close the browser
+7. Run `AfterSuite()` function
+
+
+## Mocha
+
+CodeceptJS is built on top of the [Mocha testing framework](https://mochajs.org/), but for the most part it is hidden beneath the CodeceptJS API.
+
+There are two places Mocha shows up.
+
+1. [Mocha Reports](reports.md) allow you to customize the result output into various formats.
+
+2. Configuring the test runner behavior so that it stops on the first failure, using Mocha's **bail** feature.
+
+## Feature
+
+Features name and group a bunch of scenarios.
+The feature name can contain tags to help with filtering tests to run.
+
+
+## Scenario
+
+Each test is a `Scenario`.
+
+It takes an actor `I` as a parameter, and possible other parameters representing page objects that the test needs.
+
+```js
+Feature('CodeceptJS Demonstration');
+
+Scenario('test some forms', (I) => {
+ I.amOnPage('/documentation');
+ I.click('Create User');
+ I.see('User is valid');
+});
+
+Scenario('test title is Example', (I) => {
+ I.amOnPage('/documentation');
+ I.seeInTitle('Example application');
+});
+```
+
+
+* `xScenario` - skips this test
+* `Scenario.only` - executes only this test
+
+```js
+Feature('CodeceptJS Demonstration');
+
+xScenario('test some forms', (I) => {
+ I.amOnPage('/documentation');
+ I.click('Create User');
+ I.see('User is valid');
+ I.dontSeeInCurrentUrl('/documentation');
+});
+
+Scenario.only('test title is Example', (I) => {
+ I.amOnPage('/documentation');
+ I.seeInTitle('Example application');
+});
+```
+
+
+## Before
+
+Common preparation steps like opening a web page, logging in a user, can be placed in `Before` or `Background` hook:
+
+```js
+Feature('CodeceptJS Demonstration');
+
+Before((I) => { // or Background
+ I.amOnPage('/documentation');
+});
+
+Scenario('test some forms', (I) => {
+ I.click('Create User');
+ I.see('User is valid');
+ I.dontSeeInCurrentUrl('/documentation');
+});
+
+Scenario('test title', (I) => {
+ I.seeInTitle('Example application');
+});
+```
+
+Same as `Before` you can use `After` to run teardown for each scenario.
+
+## After
+
+Common cleanup that is run after each test, but before the browser is closed.
+
+```js
+Feature('CodeceptJS Demonstration');
+
+After((I) => { // or Background
+ I.click('Logout');
+});
+
+Scenario('test some forms', (I) => {
+ I.click('Create User');
+ I.see('User is valid');
+ I.dontSeeInCurrentUrl('/documentation');
+});
+
+Scenario('test title', (I) => {
+ I.seeInTitle('Example application');
+});
+```
+
+
+## BeforeSuite
+
+If you need to run complex setup before all tests and teardown this afterwards you can use `BeforeSuite` and `AfterSuite`
+functions. `BeforeSuite` and `AfterSuite` have access to `I` object, but `BeforeSuite/AfterSuite` don't have an access to the browser because it's not running at this moment.
+You can use them to execute handlers that will setup your environment. `BeforeSuite/AfterSuite` will work only for a file where it was declared (so you can declare different setups for files)
+
+```js
+BeforeSuite((I) => {
+ I.syncDown('testfolder');
+});
+
+AfterSuite((I) => {
+ I.syncUp('testfolder');
+ I.clearDir('testfolder');
+});
+```
+
+[Here are some ideas](https://github.com/Codeception/CodeceptJS/pull/231#issuecomment-249554933) where to use BeforeSuite hooks.
+
+
+## AfterSuite
+
+
+## Skipping
+
+Like in Mocha you can use `x` and `only` to skip tests or making a single test to run.
+
+* `xScenario` - skips current test
+* `Scenario.only` - executes only the current test
+
+---
+
+### Next: [Locators >>>](locators.md)
+
+---
diff --git a/docs/locators.md b/docs/locators.md
index 78081cdb6..f068e19ca 100644
--- a/docs/locators.md
+++ b/docs/locators.md
@@ -205,4 +205,42 @@ ID locators are best to select the exact semantic element in web and mobile test
* `#user` or `{ id: 'user' }` finds element with id="user"
* `~user` finds element with accessibility id "user" (in Mobile testing) or with `aria-label=user`.
-### done()
\ No newline at end of file
+## Within
+
+To specify the exact area on a page where actions can be performed you can use `within` function.
+Everything executed in its context will be narrowed to context specified by locator:
+
+Usage: `within('section', ()=>{})`
+
+```js
+I.amOnPage('https://github.com');
+within('.js-signup-form', () => {
+ I.fillField('user[login]', 'User');
+ I.fillField('user[email]', 'user@user.com');
+ I.fillField('user[password]', 'user@user.com');
+ I.click('button');
+});
+I.see('There were problems creating your account.');
+```
+
+`within` can also work with [iframes](acceptance.md#iframes)
+
+When running steps inside a within block will be shown with a shift:
+
+
+
+Within can return a value which can be used in a scenario:
+
+```js
+// inside async function
+const val = await within('#sidebar', () => {
+ return I.grabTextFrom({ css: 'h1' });
+});
+I.fillField('Description', val);
+```
+
+---
+
+### Next: [Debugging >>>](debugging.md)
+
+---
diff --git a/docs/mobile.md b/docs/mobile.md
index d0ad2ebe2..372f66164 100644
--- a/docs/mobile.md
+++ b/docs/mobile.md
@@ -284,4 +284,3 @@ Just as you can specify android, and ios-specific locators, you can do so for we
I.click({web: '#login', ios: '//UIAApplication[1]/UIAWindow[1]/UIAButton[1]'});
```
-## done()
diff --git a/docs/multi-test.svg b/docs/multi-test.svg
new file mode 100644
index 000000000..88c1433b7
--- /dev/null
+++ b/docs/multi-test.svg
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/docs/multi.md b/docs/multi.md
new file mode 100644
index 000000000..8ebacfeb6
--- /dev/null
+++ b/docs/multi.md
@@ -0,0 +1,174 @@
+# Multiple and Parallel Testing
+
+Multiple is a way to run the same set of tests using different browsers.
+
+Parallel testing is when many instances of the same browser are used at the same time to cut down on execution time.
+
+These two concepts can be combined.
+
+## Multiple Browsers Execution
+
+
+
+This is useful if you want to execute same tests but on different browsers and with different configurations or different tests on same browsers in parallel.
+
+Create `multiple` section in configuration file, and fill it with run suites. Each suite should have `browser` array with browser names or driver helper's configuration:
+```js
+"multiple": {
+ "basic": {
+ // run all tests in chrome and firefox
+ "browsers": ["chrome", "firefox"]
+ },
+
+ "smoke": {
+ "browsers": [
+ "firefox",
+ // replace any config values from WebDriver helper
+ {
+ "browser": "chrome",
+ "windowSize": "maximize",
+ "desiredCapabilities": {
+ "acceptSslCerts": true
+ }
+ },
+ ]
+ },
+}
+```
+
+You can use `grep` and `outputName` params to filter tests and output directory for suite:
+```js
+"multiple": {
+ "smoke": {
+ // run only tests containing "@smoke" in name
+ "grep": "@smoke",
+
+ // store results into `output/smoke` directory
+ "outputName": "smoke",
+
+ "browsers": [
+ "firefox",
+ {"browser": "chrome", "windowSize": "maximize"}
+ ]
+ }
+}
+```
+
+Then tests can be executed using `run-multiple` command.
+
+Run all suites for all browsers:
+
+```sh
+codeceptjs run-multiple --all
+```
+
+Run `basic` suite for all browsers
+
+```sh
+codeceptjs run-multiple basic
+```
+
+Run `basic` suite for chrome only:
+
+```sh
+codeceptjs run-multiple basic:chrome
+```
+
+Run `basic` suite for chrome and `smoke` for firefox
+
+```sh
+codeceptjs run-multiple basic:chrome smoke:firefox
+```
+
+Run basic tests with grep and junit reporter
+
+```sh
+codeceptjs run-multiple basic --grep signin --reporter mocha-junit-reporter
+```
+
+Run regression tests specifying different config path:
+
+```sh
+codeceptjs run-multiple regression -c path/to/config
+```
+
+Each executed process uses custom folder for reports and output. It is stored in subfolder inside an output directory. Subfolders will be named in `suite_browser` format.
+
+Output is printed for all running processes. Each line is tagged with a suite and browser name:
+
+```sh
+[basic:firefox] GitHub --
+[basic:chrome] GitHub --
+[basic:chrome] it should not enter
+[basic:chrome] ✓ signin in 2869ms
+
+[basic:chrome] OK | 1 passed // 30s
+[basic:firefox] it should not enter
+[basic:firefox] ✖ signin in 2743ms
+
+[basic:firefox] -- FAILURES:
+```
+
+### Hooks
+
+Hooks are available when using the `run-multiple` command to perform actions before the test suites start and after the test suites have finished. See [Hooks](hooks.md#bootstrap-teardown) for an example.
+
+## Parallel Execution
+
+
+
+CodeceptJS can be configured to run tests in parallel.
+
+When enabled, it collects all test files and executes them in parallel by the specified amount of chunks. Given we have five test scenarios (`a_test.js`,`b_test.js`,`c_test.js`,`d_test.js` and `e_test.js`), by setting `"chunks": 2` we tell the runner to run two suites in parallel. The first suite will run `a_test.js`,`b_test.js` and `c_test.js`, the second suite will run `d_test.js` and `e_test.js`.
+
+
+```js
+"multiple": {
+ "parallel": {
+ // Splits tests into 2 chunks
+ "chunks": 2
+ }
+}
+```
+
+To execute them use `run-multiple` command passing configured suite, which is `parallel` in this example:
+
+```
+codeceptjs run-multiple parallel
+```
+
+Grep and multiple browsers are supported. Passing more than one browser will multiply the amount of suites by the amount of browsers passed. The following example will lead to four parallel runs.
+
+```js
+"multiple": {
+ // 2x chunks + 2x browsers = 4
+ "parallel": {
+ // Splits tests into chunks
+ "chunks": 2,
+ // run all tests in chrome and firefox
+ "browsers": ["chrome", "firefox"]
+ },
+}
+```
+
+Passing a function will enable you to provide your own chunking algorithm. The first argument passed to you function is an array of all test files, if you enabled grep the test files passed are already filtered to match the grep pattern.
+
+```js
+"multiple": {
+ "parallel": {
+ // Splits tests into chunks by passing an anonymous function,
+ // only execute first and last found test file
+ "chunks": (files) => {
+ return [
+ [ files[0] ], // chunk 1
+ [ files[files.length-1] ], // chunk 2
+ ]
+ },
+ // run all tests in chrome and firefox
+ "browsers": ["chrome", "firefox"]
+ }
+}
+```
+
+Note: Chunking will be most effective if you have many individual test files that contain only a small amount of scenarios. Otherwise the combined execution time of many scenarios or big scenarios in one single test file potentially lead to an uneven execution time.
+
diff --git a/docs/nightmare.md b/docs/nightmare.md
index 9f94c4575..eac6d8138 100644
--- a/docs/nightmare.md
+++ b/docs/nightmare.md
@@ -221,4 +221,3 @@ use locate found elements on a page and return attribute from the first of them.
* [Nightmare Tutorial](http://codenroll.it/acceptance-testing-with-codecept-js/) by jploskonka.
-## done()
diff --git a/docs/nightmare.png b/docs/nightmare.png
new file mode 100644
index 000000000..050138980
Binary files /dev/null and b/docs/nightmare.png differ
diff --git a/docs/pageobjects.md b/docs/pageobjects.md
index e14410ae4..cc1e2e3db 100644
--- a/docs/pageobjects.md
+++ b/docs/pageobjects.md
@@ -233,4 +233,3 @@ Scenario('search @grop', (I, Data) => {
This requires `./data.js` module and assigns it to `Data` argument in a test.
-### done()
diff --git a/docs/parallel-test.svg b/docs/parallel-test.svg
new file mode 100644
index 000000000..e980fc7d8
--- /dev/null
+++ b/docs/parallel-test.svg
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/docs/protractor.png b/docs/protractor.png
new file mode 100644
index 000000000..3a84d2c06
Binary files /dev/null and b/docs/protractor.png differ
diff --git a/docs/puppeteer.md b/docs/puppeteer.md
index 781887551..27386844a 100644
--- a/docs/puppeteer.md
+++ b/docs/puppeteer.md
@@ -162,9 +162,9 @@ within('.todoapp', () => {
I.see('0 items left', '.todo-count');
```
-CodeceptJS allows you to implement custom actions like `I.createTodo` or use **PageObjects**. Learn how to improve your tests in [PageObjects](http://codecept.io/pageobjects/) guide.
+CodeceptJS allows you to implement custom actions like `I.createTodo` or use **PageObjects**. Learn how to improve your tests in [PageObjects](pageobjects.md) guide.
-`within` can also work with [iframes](/acceptance/#iframes)
+`within` can also work with [iframes](acceptance.md#iframes)
When running steps inside a within block will be shown with a shift:
@@ -194,6 +194,5 @@ async renderPageToPdf() {
The same way you can also access `browser` object to implement more actions or handle events. [Learn more about Helpers](http://codecept.io/helpers/) in the corresponding guide.
-## done()
Yes, also the [demo project is available on GitHub](https://github.com/DavertMik/codeceptjs-todomvc-puppeteer)
diff --git a/docs/puppeteer.png b/docs/puppeteer.png
new file mode 100644
index 000000000..cdd6905f8
Binary files /dev/null and b/docs/puppeteer.png differ
diff --git a/docs/quickstart.md b/docs/quickstart.md
deleted file mode 100644
index d8d899e51..000000000
--- a/docs/quickstart.md
+++ /dev/null
@@ -1,212 +0,0 @@
-# QuickStart
-
-**NodeJS v 8.9** and higher required to start.
-CodeceptJS is multi-backend testing framework. It can execute tests using different libraries like webdriverio, Puppeteer, Protractor, etc.
-
-* In this guide we will use [Google Chrome **Puppeteer**](https://github.com/GoogleChrome/puppeteer) as a driver for browsers. This allows us to start in a minutes with no extra tools installed.
-* If you are familiar with Selenium, you can choose classical [**Selenium WebDriver** setup](#using-selenium-webdriver).
-* Also, look at [complete installation reference](https://codecept.io/installation/).
-
-
-## Using Puppeteer
-
-
-
-
-
-1) Install CodeceptJS with Puppeteer
-
-```
-npm install codeceptjs puppeteer --save-dev
-```
-
-(due to [this issue in Puppeteer](https://github.com/GoogleChrome/puppeteer/issues/375), we install it locally)
-
-
-2) Initialize CodeceptJS in current directory by running:
-
-```sh
-./node_modules/.bin/codeceptjs init
-```
-
-(use `node node_modules/.bin/codeceptjs` on Windows)
-
-3) Answer questions. Agree on defaults, when asked to select helpers choose **Puppeteer**.
-
-```sh
-? What helpers do you want to use?
- ◯ WebDriver
- ◯ Protractor
-❯◉ Puppeteer
- ◯ Appium
- ◯ Nightmare
- ◯ FileSystem
-```
-
-4) Create First Test.
-
-```bash
-./node_modules/.bin/codeceptjs gt
-```
-
-5) Enter a test name. Open a generated file in your favorite JavaScript editor.
-
-```js
-Feature('My First Test');
-
-Scenario('test something', (I) => {
-
-});
-```
-
-6) Write a simple scenario
-
-```js
-Feature('My First Test');
-
-Scenario('test something', (I) => {
- I.amOnPage('https://github.com');
- I.see('GitHub');
-});
-```
-
-7) Run a test:
-
-```
-./node_modules/.bin/codeceptjs run --steps
-```
-
-The output should be similar to this:
-
-```bash
-My First Test --
- test something
- • I am on page "https://github.com"
- • I see "GitHub"
- ✓ OK
-```
-
-Puppeteer starts a browser without showing its window. To see the browser, edit `codecept.json` config and set `show: true` for Puppeteer:
-
-```js
-{
- "helpers": {
- "Puppeteer": {
- "url": "http://localhost",
- "show": true,
- }
- }
-}
-```
-
-Rerun the test to see the browser.
-
----
-
-### Next: [CodeceptJS with Puppeteer >>>](https://codecept.io/puppeteer/)
-### Next: [CodeceptJS Basics >>>](https://codecept.io/basics/)
-### Next: [Demo Project](https://github.com/DavertMik/codeceptjs-todomvc-puppeteer)
-
-
----
-
-## Using Selenium WebDriver
-
-1) Install CodeceptJS with webdriverio library
-
-```
-[sudo] npm install -g codeceptjs webdriverio
-```
-
-2) Initialize CodeceptJS in current directory by running:
-
-```sh
-codeceptjs init
-```
-
-3) Answer questions. Agree on defaults, when asked to select helpers choose **WebDriver**.
-
-```sh
-? What helpers do you want to use?
-❯◉ WebDriver
- ◯ Protractor
- ◯ Puppeteer
- ◯ Appium
- ◯ Nightmare
- ◯ FileSystem
-```
-
-4) Create First Test.
-
-```bash
-codeceptjs gt
-```
-
-5) Enter a test name. Open a generated file in your favorite JavaScript editor.
-
-```js
-Feature('My First Test');
-
-Scenario('test something', (I) => {
-
-});
-```
-
-6) Write a simple scenario
-
-```js
-Feature('My First Test');
-
-Scenario('test something', (I) => {
- I.amOnPage('https://github.com');
- I.see('GitHub');
-});
-```
-
-7) Prepare Selenium Server
-
-To execute tests in Google Chrome browser running Selenium Server with ChromeDriver is required.
-
-Use [selenium-standalone](https://www.npmjs.com/package/selenium-standalone) from NPM to install and run them:
-
-```sh
-[sudo] npm install -g selenium-standalone
-selenium-standalone install
-selenium-standalone start
-```
-
-
-8) Run a test:
-
-```
-codeceptjs run --steps
-```
-
-If everything is done right, you will see in console:
-
-```bash
-My First Test --
- test something
- • I am on page "https://github.com"
- • I see "GitHub"
- ✓ OK
-```
-
----
-
-### Next: [CodeceptJS Basics >>>](https://codecept.io/basics/)
-### Next: [Acceptance Testing in CodeceptJS >>>](https://codecept.io/acceptance/)
-
----
-
-## Using Protractor
-
-[**Follow corresponding guide >>**](https://codecept.io/angular/)
-
-## Using Appium
-
-[**Follow corresponding guide >>**](https://codecept.io/mobile/)
-
-## Using NightmareJS
-
-[**Follow corresponding guide >>**](https://codecept.io/nightmare/)
diff --git a/docs/quickstart/codecept-overview.svg b/docs/quickstart/codecept-overview.svg
new file mode 100644
index 000000000..f92a96c42
--- /dev/null
+++ b/docs/quickstart/codecept-overview.svg
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/docs/quickstart/github1.png b/docs/quickstart/github1.png
new file mode 100644
index 000000000..0fe3e68c5
Binary files /dev/null and b/docs/quickstart/github1.png differ
diff --git a/docs/quickstart/github2.png b/docs/quickstart/github2.png
new file mode 100644
index 000000000..c9f6f022b
Binary files /dev/null and b/docs/quickstart/github2.png differ
diff --git a/docs/quickstart/github3.png b/docs/quickstart/github3.png
new file mode 100644
index 000000000..c08811c0d
Binary files /dev/null and b/docs/quickstart/github3.png differ
diff --git a/docs/quickstart/installation.md b/docs/quickstart/installation.md
new file mode 100644
index 000000000..9c9316bf4
--- /dev/null
+++ b/docs/quickstart/installation.md
@@ -0,0 +1,50 @@
+# Installation
+
+
+## [Installation](https://www.youtube.com/watch?v=FPFG1rBNJ64)
+
+
+
+Video provided by our community member **[@ontytoom](http://github.com/ontytoom)**.
+
+
+## Local Installation
+
+CodeceptJS can be installed via NPM, together with a suitable driver to connect to the browser:
+
+```sh
+npm install --save-dev codeceptjs webdriverio
+# or
+npm install --save-dev codeceptjs protractor
+# or
+npm install --save-dev codeceptjs puppeteer
+# or
+npm install --save-dev codeceptjs nightmare
+```
+
+then it can be started as
+
+```sh
+./node_modules/.bin/codeceptjs
+```
+
+Local installations are easier to reproduce on other machines. This is useful on CI/Build servers that should install all the needed tools automatically.
+
+## WebDriver
+
+WebDriver based helpers like WebDriver, Protractor, Selenium WebDriver will require [Selenium Server](http://codecept.io/helpers/WebDriverIO/#selenium-installation) or [PhantomJS](http://codecept.io/helpers/WebDriverIO/#phantomjs-installation) installed. They will also require ChromeDriver or GeckoDriver to run corresponding browsers.
+
+We recommend to install them using an NPM package:
+
+[Selenium Standalone](https://www.npmjs.com/package/selenium-standalone) will install and run Selenium, ChromeDriver, Firefox Driver with one package.
+
+```sh
+npm install --save-dev codeceptjs webdriverio
+[sudo] npm install -g selenium-standalone
+selenium-standalone install
+selenium-standalone start
+```
+
+This installs Selenium globally, which makes the `selenium-standalone` command available in the PATH.
+
+Note that Selenium is [Java](https://www.java.com/en/download/) based, so you may need to install or update that first.
diff --git a/docs/quickstart/nightmare.md b/docs/quickstart/nightmare.md
new file mode 100644
index 000000000..6ec2da391
--- /dev/null
+++ b/docs/quickstart/nightmare.md
@@ -0,0 +1,115 @@
+# Nightmare Quickstart
+
+[NightmareJS](http://www.nightmarejs.org) is a modern Electron based testing framework which allows to execute tests in headless mode as well as in window mode for debug purposes.
+Nightmare is in active development and has nice API for writing acceptance tests.
+Unfortunately, as all other JavaScript testing frameworks it has its own very custom API.
+What if you choose it for a project and suddenly you realize that you need something more powerful, like Selenium?
+Yes, that might be a problem if you are not using CodeceptJS.
+The one idea behind CodeceptJS is to unify different testing backends under one API, so you could easily write tests the same way no matter what engines you use: webdriverio, Protractor, or Nightmare.
+
+## Install Codecept and Nightmare
+
+To start you need CodeceptJS and Nightmare installed.
+
+```bash
+npm install -g codeceptjs nightmare
+```
+
+## Setup a test
+
+And a basic Codecept test project initialized
+
+```sh
+codeceptjs init
+```
+
+You will be asked for a Helper to use, you should select Nightmare and provide the url of a website you are testing.
+We will test `https://github.com`
+
+Answer the questions. Agree on defaults, when asked to select helpers choose **Nightmare**.
+
+```sh
+? What helpers do you want to use?
+ ◯ WebDriver
+ ◯ Protractor
+ ◯ Puppeteer
+ ◯ Appium
+❯◉ Nightmare
+ ◯ FileSystem
+```
+
+Create First Test. The `gt` command *Generates a Test* file for us. and adds it to the Codecept configuration file.
+
+```bash
+./node_modules/.bin/codeceptjs gt
+```
+
+Enter a test name. Open a generated file in your favorite JavaScript editor.
+
+```js
+Feature('My First Test');
+
+Scenario('test something', (I) => {
+
+});
+```
+
+Write a simple scenario
+
+```js
+Feature('My First Test');
+
+Scenario('test something', (I) => {
+ I.amOnPage('https://github.com');
+ I.see('GitHub');
+});
+```
+
+## Run the test
+
+```
+./node_modules/.bin/codeceptjs run --steps
+```
+
+The output should be similar to this:
+
+```bash
+My First Test --
+ test something
+ • I am on page "https://github.com"
+ • I see "GitHub"
+ ✓ OK
+```
+
+
+## Configuring Nightmare
+
+Enable `Nightmare` helper in `codecept.json` config:
+
+```js
+{ // ..
+ "helpers": {
+ "Nightmare": {
+ "url": "http://localhost",
+ "show": false,
+ "restart": false
+ }
+ }
+ // ..
+}
+```
+
+Turn on the `show` option if you want to follow test progress in a window. This is very useful for debugging.
+All other options can be taken from [NightmareJS API](https://github.com/segmentio/nightmare#api).
+
+Turn off the `restart` option if you want to run your suite in a single browser instance.
+
+Option `waitForAction` defines how long to wait after a click, doubleClick or pressKey action is performed.
+Test execution may happen much faster than the response is rendered, so make sure you set a proper delay value.
+By default CodeceptJS waits for 500ms.
+
+
+## Additional Links
+
+* [Nightmare Tutorial](http://codenroll.it/acceptance-testing-with-codecept-js/) by jploskonka.
+
diff --git a/docs/quickstart/protractor.md b/docs/quickstart/protractor.md
new file mode 100644
index 000000000..b39f598bd
--- /dev/null
+++ b/docs/quickstart/protractor.md
@@ -0,0 +1,130 @@
+# Protractor Quickstart
+
+## Introduction
+
+[Protractor](http://www.protractortest.org/#/) is an official tool for testing AngularJS applications.
+CodeceptJS should not be considered as alternative to Protractor but a testing framework utilizing this powerful library.
+
+There is no magic in testing of AngularJS application in CodeceptJS.
+You just execute regular Protractor commands, packed in a simple high-level API.
+
+## Setting up CodeceptJS with Protractor
+
+To start using CodeceptJS you will need to install it via NPM and initialize it in directory with tests.
+
+```bash
+[sudo] npm install -g codeceptjs
+npm install --save-dev protractor
+```
+
+Protractor uses webdriver to talk to the browser, so you need to install Selenium as well.
+
+```bash
+[sudo] npm install -g selenium-standalone
+selenium-standalone install
+selenium-standalone start
+```
+
+## Define Test Project
+
+```bash
+codeceptjs init
+
+ Welcome to CodeceptJS initialization tool
+ It will prepare and configure a test environment for you
+
+Installing
+? Where are your tests located? ./*_test.js
+
+? What helpers do you want to use?
+ ◯ WebDriver
+❯◉ Protractor
+ ◯ Puppeteer
+ ◯ Appium
+ ◯ Nightmare
+ ◯ FileSystem
+
+? What helpers do you want to use? Protractor
+Configure helpers...
+? [Protractor] Base url of site to be tested http://localhost
+? [Protractor] Protractor driver (local, direct, session, hosted, sauce, browserstack) hosted
+? [Protractor] Browser in which testing will be performed chrome
+? [Protractor] Root element of AngularJS application body
+```
+
+You will be asked questions about initial configuration, make sure you select Protractor helper.
+If you didn't have Protractor library it **will be installed**.
+
+Please use `http://todomvc.com/examples/angularjs/` as a url for Protractor helper.
+
+The following config is created in `codecept.json` file:
+
+```json
+{
+ "tests": "./*_test.js",
+ "output": "./output",
+ "helpers": {
+ "Protractor": {
+ "url": "https://todomvc.com/examples/angularjs/",
+ "driver": "hosted",
+ "browser": "chrome",
+ "rootElement": "body"
+ }
+ },
+ "include": {
+ "I": "./steps_file.js"
+ },
+ "name": "todoangular"
+}
+```
+
+First test can be generated with `gt` (Generate Test) command:
+
+```bash
+codeceptjs gt
+```
+
+After that you can start writing your first CodeceptJS/Angular tests.
+Please look into the reference of [Protractor helper](../helpers/Protractor.md) for all available actions.
+You can also run `list` command to see methods of I:
+
+```bash
+codeceptjs list
+```
+
+## Writing First Test
+
+At first a page should be opened to proceed, we use `amOnPage` command for that. As we already specified full URL to TodoMVC app,
+we can pass relative path into it instead of absolute url:
+
+In CodeceptJS assertion commands have `see` or `dontSee` prefix:
+
+```js
+Feature('Todo MVC');
+
+Scenario('create todo item', (I) => {
+ I.amOnPage('/');
+ I.dontSeeElement('#todo-count');
+ I.see('todos')
+});
+```
+
+## Run the test
+
+A test can be executed with `run` command, we recommend to use `--steps` options to follow step-by-step execution:
+
+```sh
+$ codeceptjs run --steps
+
+CodeceptJS 1.2.0
+Using the selenium server at http://localhost:4444/wd/hub
+
+TodoMvc --
+ create todo item
+ • I am on page "/"
+ • I dont see element "#todo-count"
+```
+
+---
+
+### Next: [CodeceptJS Basics >>>](../basics.md)
diff --git a/docs/quickstart/puppeteer.md b/docs/quickstart/puppeteer.md
new file mode 100644
index 000000000..157861984
--- /dev/null
+++ b/docs/quickstart/puppeteer.md
@@ -0,0 +1,157 @@
+# Puppeteer Quickstart
+
+
+## Install CodeceptJS with Puppeteer
+
+```sh
+npm install codeceptjs puppeteer --save-dev
+
+> puppeteer@1.10.0 install C:\\Temp\\c1\\node_modules\\puppeteer
+> node install.js
+
+Downloading Chromium r599821 - 135.9 Mb [====================] 98%
+```
+
+(due to [this issue in Puppeteer](https://github.com/GoogleChrome/puppeteer/issues/375), we install it locally)
+
+The Puppeteer package includes a full chromium browser that runs independent of your standard Chrome browser. This means your normal browser has no effect on your test runs, which is good. Your tests should be isolated from the local environment.
+
+## Define test project
+
+Initialize CodeceptJS in current directory by running:
+
+```sh
+./node_modules/.bin/codeceptjs init
+```
+
+(use `node node_modules/.bin/codeceptjs` on Windows)
+
+Answer questions. Agree on defaults, when asked to select helpers choose **Puppeteer**.
+We will test `https://github.com` so enter that when asked for a URL
+
+```sh
+
+ Welcome to CodeceptJS initialization tool
+ It will prepare and configure a test environment for you
+
+Installing
+? Where are your tests located? ./*_test.js
+
+? What helpers do you want to use?
+ ◯ WebDriver
+ ◯ Protractor
+❯◉ Puppeteer
+ ◯ Appium
+ ◯ Nightmare
+ ◯ FileSystem
+
+? What helpers do you want to use? Puppeteer
+? Where should logs, screenshots, and reports to be stored? ./output
+? Would you like to extend I object with custom steps? Yes
+? Do you want to choose localization for tests? English (no localization)
+? Where would you like to place custom steps? ./steps_file.js
+Configure helpers...
+? [Puppeteer] Base url of site to be tested https://github.com
+Steps file created at ./steps_file.js
+Config created at ./codecept.json
+Directory for temporary output files created at `_output`
+```
+
+The `codecept.json` configuration file stores our choices. It looks like this:
+
+```json
+{
+ "tests": "./*_test.js",
+ "timeout": 10000,
+ "output": "./output",
+ "helpers": {
+ "Puppeteer": {
+ "url": "https://github.com"
+ }
+ },
+ "include": {
+ "I": "./steps_file.js"
+ },
+ "bootstrap": false,
+ "mocha": {},
+ "name": "dirname"
+}
+```
+
+## Create First Test
+
+Use the command GT (for *Generate Test*) to create our first test:
+
+```bash
+./node_modules/.bin/codeceptjs gt
+
+Creating a new test...
+----------------------
+? Filename of a test First
+? Feature which is being tested My First Test
+Test for First was created in ./First_test.js
+```
+
+Enter a test name. Open the generated file in your favorite JavaScript editor.
+
+```js
+Feature('My First Test');
+
+Scenario('test something', (I) => {
+
+});
+```
+
+Write a simple scenario
+
+```js
+Feature('My First Test');
+
+Scenario('test something', (I) => {
+ I.amOnPage('/');
+ I.see('GitHub');
+ I.dontSee('Microsoft');
+});
+```
+
+First we need to go to a page; we use `amOnPage` command for that. As we already specified full URL to TodoMVC app,
+we can pass relative path into it instead of absolute url.
+
+In CodeceptJS assertion commands have `see` or `dontSee` prefix.
+
+## Run test
+
+```
+./node_modules/.bin/codeceptjs run --steps
+```
+The `--steps` flag tells Codecept to list out the steps as they are completed.
+The output should be similar to this:
+
+```bash
+My First Test --
+ test something
+ • I am on page "https://github.com"
+ • I see "GitHub"
+ ✓ OK
+```
+
+Puppeteer starts a browser without showing its window. To see the browser, edit `codecept.json` config and set `show: true` for Puppeteer:
+
+```js
+{
+ "helpers": {
+ "Puppeteer": {
+ "url": "https://github.com",
+ "show": true
+ }
+ }
+}
+```
+
+Rerun the test to see the browser performing the test actions.
+
+---
+
+### Next: [CodeceptJS Basics >>>](../basics.md)
+
+### Next: [Demo Project](https://github.com/DavertMik/codeceptjs-todomvc-puppeteer)
diff --git a/docs/quickstart/quickstart.md b/docs/quickstart/quickstart.md
new file mode 100644
index 000000000..0aae59afa
--- /dev/null
+++ b/docs/quickstart/quickstart.md
@@ -0,0 +1,58 @@
+# Overview
+
+CodeceptJS is multi-backend testing framework. It can execute tests using different libraries like webdriverio, Puppeteer, Protractor, etc. Note that these libraries need to be installed separately - they are not included in the CodeceptJS package.
+
+CodeceptJS is an acceptance testing framework. In the diversified world of JavaScript testing libraries it aims to create a unified high level API for end-to-end testing, powered by different backends.
+
+CodeceptJS allows you to write a test and switch in config execution drivers: will it be *wedriverio*, *puppeteer*, or *protractor* depends on you.
+This way you aren't be bound to implementation, and your acceptance tests will work no matter which framework is running them.
+
+
+
+CodeceptJS contains **helpers** that talk to **drivers**. The drivers control a **browser**, usually in headless mode - which means that the browser window is not visible while the test is running.
+
+You need to install
+* Node and Node Package Manager (NPM)
+* CodeceptJS
+* A browser
+* A suitable driver (webdriver, puppeteer, protractor, nightmare)
+
+You need to provide
+* a web page to test
+* a test script
+
+CodeceptJS takes care of connecting your test script to the browser through a helper and its corresponding driver.
+
+
+## NodeJS v8.9
+
+**NodeJS v 8.9** and higher required to start. Using an older version of NodeJS will result in errors.
+Check your Node version on the command-line
+
+```sh
+> node --version
+v8.11.1
+```
+
+## Quickstarts
+
+There are separate Quickstarts for all the major drivers:
+
+| | |
+|:----:|:----|
+| [](puppeteer.md) | ## [Puppeteer](puppeteer.md) |
+| [](selenium.md) | ## [WebDriver](selenium.md) |
+| [](protractor.md) | Protractor |
+| [](nightmare.md) | Nightmare |
+
+All of the quickstarts show you how to test GitHub.
+
+
+
+## CodeceptJS in 2 minutes
+
+
+
+---
+
+### Next: [Puppeteer Quickstart >>>](puppeteer.md)
diff --git a/docs/quickstart/selenium.md b/docs/quickstart/selenium.md
new file mode 100644
index 000000000..156b32f4b
--- /dev/null
+++ b/docs/quickstart/selenium.md
@@ -0,0 +1,163 @@
+# Quickstart with Selenium WebDriver
+
+Selenium is the original browser-driver, and it provides a standard interface to many different browsers. It is popular for cross-browser testing, and for testing via cloud-based services like SauceLabs.
+
+## Install CodeceptJS and Selenium Server
+
+Install CodeceptJS with webdriverio library globally.
+
+```
+[sudo] npm install -g codeceptjs webdriverio
+```
+
+## Install Selenium Server.
+
+To execute tests in Google Chrome browser running Selenium Server with ChromeDriver is required.
+
+Use [selenium-standalone](https://www.npmjs.com/package/selenium-standalone) from NPM to install and run them, then install and start the Selenium server.
+The Selenium server listens for commands from Codecept, and controls the browser for us.
+
+```sh
+[sudo] npm install -g selenium-standalone
+selenium-standalone install
+```
+
+## Setup a test
+
+Initialize CodeceptJS in current directory by running:
+
+```sh
+codeceptjs init
+```
+
+Answer questions. Agree on defaults, when asked to select helpers choose **WebDriver**.
+We will test `https://github.com` so enter that when asked for a URL
+
+```sh
+ Welcome to CodeceptJS initialization tool
+ It will prepare and configure a test environment for you
+
+Installing
+? Where are your tests located? ./*_test.js
+
+? What helpers do you want to use?
+❯◉ WebDriver
+ ◯ Protractor
+ ◯ Puppeteer
+ ◯ Appium
+ ◯ Nightmare
+ ◯ FileSystem
+
+? What helpers do you want to use? WebDriver
+? Where should logs, screenshots, and reports to be stored? ./output
+? Would you like to extend I object with custom steps? Yes
+? Do you want to choose localization for tests? English (no localization)
+? Where would you like to place custom steps? ./steps_file.js
+Configure helpers...
+? [WebDriver] Base url of site to be tested https://github.com
+? [WebDriver] Browser in which testing will be performed chrome
+```
+
+The `codecept.json` configuration file stores our choices. It looks like this:
+
+```json
+{
+ "tests": "./*_test.js",
+ "output": "./output",
+ "helpers": {
+ "WebDriver": {
+ "url": "https://github.com",
+ "browser": "chrome"
+ }
+ },
+ "include": {
+ "I": "./steps_file.js"
+ },
+ "name": "dirname"
+}
+```
+
+## Create First Test
+
+The `gt` command *Generates a Test* file for us. and adds it to the Codecept configuration file.
+
+```bash
+codeceptjs gt
+
+Creating a new test...
+----------------------
+? Filename of a test First
+? Feature which is being tested My First Test
+Test for First was created in ./First_test.js
+```
+
+Enter a test name. Open the generated file in your favorite JavaScript editor.
+
+```js
+Feature('My First Test');
+
+Scenario('test something', (I) => {
+
+});
+```
+
+Write a simple scenario
+
+```js
+Feature('My First Test');
+
+Scenario('test something', (I) => {
+ I.amOnPage('https://github.com');
+ I.see('GitHub');
+});
+```
+
+## Start Selenium
+
+Before we can run the tests, we need to make sure that the Selenium server is running.
+
+```sh
+selenium-standalone start
+```
+
+The selenium server should start up, and be ready to accept commands.
+
+## Run tests
+
+```
+codeceptjs run --steps
+```
+
+If everything is done right, you will see in console:
+
+```bash
+My First Test --
+ test something
+ • I am on page "https://github.com"
+ • I see "GitHub"
+ ✓ OK
+```
+
+You should also see commands fly past on the selenium server log.
+
+```
+00:12:44.758 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.0, revision: 2ecb7d9a
+00:12:44.890 INFO [GridLauncherV3.lambda$buildLaunchers$3] - Launching a standalone Selenium Server on port 4444
+00:12:45.843 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 4444
+Selenium started
+00:13:41.097 INFO [ActiveSessionFactory.apply] - Capabilities are: {
+ "browserName": "chrome"
+}
+00:13:41.100 INFO [ActiveSessionFactory.lambda$apply$11] - Matched factory org.openqa.selenium.grid.session.remote.ServicedSession$Factory (provider: org.openqa.selenium.chrome.ChromeDriverService)
+Starting ChromeDriver 2.43.600210 (68dcf5eebde37173d4027fa8635e332711d2874a) on port 48064
+Only local connections are allowed.
+00:13:45.642 INFO [ProtocolHandshake.createSession] - Detected dialect: OSS
+00:13:46.097 INFO [RemoteSession$Factory.lambda$performHandshake$0] - Started new session b49e851599110caac64391de22a1183a (org.openqa.selenium.chrome.ChromeDriverService)
+00:13:50.870 INFO [ActiveSessions$1.onStop] - Removing session b49e851599110caac64391de22a1183a (org.openqa.selenium.chrome.ChromeDriverService)
+```
+
+---
+
+### Next: [CodeceptJS Basics >>>](../basics.md)
+
+---
diff --git a/docs/retries.md b/docs/retries.md
new file mode 100644
index 000000000..ae356e68e
--- /dev/null
+++ b/docs/retries.md
@@ -0,0 +1,68 @@
+# Retries
+
+## Retry Step
+
+If you have a step which often fails you can retry execution for this single step.
+Use `retry()` function before an action to ask CodeceptJS to retry this step on failure:
+
+```js
+I.retry().see('Welcome');
+```
+
+If you'd like to retry step more than once pass the amount as parameter:
+
+```js
+I.retry(3).see('Welcome');
+```
+
+Additional options can be provided to retry so you can set the additional options (defined in [promise-retry](https://www.npmjs.com/package/promise-retry) library).
+
+
+```js
+// retry action 3 times waiting for 0.1 second before next try
+I.retry({ retries: 3, minTimeout: 100 }).see('Hello');
+
+// retry action 3 times waiting no more than 3 seconds for last retry
+I.retry({ retries: 3, maxTimeout: 3000 }).see('Hello');
+
+// retry 2 times if error with message 'Node not visible' happens
+I.retry({
+ retries: 2,
+ when: err => err.message === 'Node not visible'
+}).seeElement('#user');
+```
+
+Pass a function to `when` option to retry only when error matches the expected one.
+
+## Auto Retry
+
+You can auto-retry a failed step by enabling [retryFailedStep Plugin](https://codecept.io/plugins/#retryfailedstep).
+
+## Retry Scenario
+
+When you need to rerun scenarios few times just add `retries` option added to `Scenario` declaration.
+
+CodeceptJS implements retries the same way [Mocha does](https://mochajs.org#retry-tests);
+You can set number of a retries for a feature:
+
+```js
+Scenario('Really complex', (I) => {
+ // test goes here
+}).retry(2);
+
+// alternative
+Scenario('Really complex', { retries: 2 }, (I) => {});
+```
+
+This scenario will be restarted two times on a failure.
+
+## Retry Feature
+
+To set this option for all scenarios in a file, add retry to a feature:
+
+```js
+Feature('Complex JS Stuff').retry(3);
+```
+
+Every Scenario inside this feature will be rerun 3 times.
+You can make an exception for a specific scenario by passing `retries` option to a Scenario.
diff --git a/docs/sessions.md b/docs/sessions.md
new file mode 100644
index 000000000..80f6ce920
--- /dev/null
+++ b/docs/sessions.md
@@ -0,0 +1,71 @@
+# Multiple Sessions
+
+CodeceptJS allows to run several browser sessions inside a test. This can be useful for testing communication between users inside a system, for instance in chats. To open another browser use `session()` function as shown in example:
+
+```js
+Scenario('test app', (I) => {
+ I.amOnPage('/chat');
+ I.fillField('name', 'davert');
+ I.click('Sign In');
+ I.see('Hello, davert');
+ session('john', () => {
+ // another session started
+ I.amOnPage('/chat');
+ I.fillField('name', 'john');
+ I.click('Sign In');
+ I.see('Hello, john');
+ });
+ // switching back to default session
+ I.fillField('message', 'Hi, john');
+ // there is a message from current user
+ I.see('me: Hi, john', '.messages');
+ session('john', () => {
+ // let's check if john received it
+ I.see('davert: Hi, john', '.messages');
+ });
+});
+```
+
+`session` function expects a first parameter to be a name of a session. You can switch back to session by using the same name.
+
+You can override config for session by passing second parameter:
+
+```js
+session('john', { browser: 'firefox' } , () => {
+ // run this steps in firefox
+ I.amOnPage('/');
+});
+```
+
+or just start session without switching to it. Call `session` passing only its name:
+
+```js
+Scenario('test', (I) => {
+ // opens 3 additional browsers
+ session('john');
+ session('mary');
+ session('jane');
+
+ I.amOnPage('/');
+
+ // switch to session by its name
+ session('mary', () => {
+ I.amOnPage('/login');
+ });
+}
+```
+`session` can return value which can be used in scenario:
+
+```js
+// inside async function
+const val = await session('john', () => {
+ I.amOnPage('/info');
+ return I.grabTextFrom({ css: 'h1' });
+});
+I.fillField('Description', val);
+```
+
+Function passed into session can use `I`, page objects, and any objects declared for the scenario.
+This function can also be declared as async (but doesn't work as generator).
+
+Also, you can use `within` inside a session but you can't call session from inside `within`.
diff --git a/docs/webdriver.png b/docs/webdriver.png
new file mode 100644
index 000000000..4e29ce2e8
Binary files /dev/null and b/docs/webdriver.png differ
diff --git a/docs/what-is-helper.md b/docs/what-is-helper.md
new file mode 100644
index 000000000..0407d01bc
--- /dev/null
+++ b/docs/what-is-helper.md
@@ -0,0 +1,73 @@
+# What is a Helper?
+
+Helpers is a core concept of CodeceptJS. A Helper is a wrapper around a driver for talking to browsers, providing unified interface around them.
+
+So we have a **Puppeteer helper** which talks to the *Puppeteer driver*, which talks to a Chrome browser.
+
+The **Nightmare helper** talks to the *Nightmare driver*, which talks to an Electron 'browser'.
+
+The **Webdriver helper** which talks the webdriver protocol to the *Webdriverio driver*, which talks to a Selenium server, which talks to a Firefox, Edge, or Chrome browser.
+
+All these helpers implement (nearly) the same API.
+
+* The **Puppeteer helper** implements `amOnPage(url)` to navigate to a URL.
+* The **Nightmare helper** and the **Webdriver helper** also implement the `amOnPage(url)` function.
+
+Methods of Helper class will be available in tests in `I` object. This abstracts test scenarios from the implementation and allows easy switching between backends.
+
+## Configuration
+
+Helpers are defined and configured in the `codecept.json` file.
+
+```js
+{ "helpers": {
+ "Nightmare": {
+ "url": "http://localhost",
+ "show": false
+} } }
+```
+
+You should only have one primary helper active at one time. Trying to configure both Puppeteer and Nightmare helpers at the same time won't work. There is a special [multi](multi.md) mode for running the same tests in multiple browsers.
+
+## Custom Helpers
+
+You can make your own helpers. These helpers are for adding your own custom functions, or for exposing a bit more of the underlying driver functionality without modifying CodeceptJS directly.
+
+These helpers get added into the config file alongside the primary helper.
+
+```js
+{ // ..
+ "helpers": {
+ "Nightmare": {
+ "url": "http://localhost",
+ "restart": false
+ },
+ "MyHelper": { }
+ }
+ // ..
+}
+```
+
+## Non-browser Helpers
+
+The REST and Filesystem helpers are assistants. They do not pretend to be browsers, but add their own special APIs to the `I` object to make tests easier to write.
+
+For example, the REST helper lets you write a test that can call a WebAPI to create a record.
+
+These would also be used alongside the main helper:
+
+```js
+{ // ..
+ "helpers": {
+ "Nightmare": {
+ "url": "http://localhost",
+ "restart": false
+ },
+ "MyHelper": { },
+ "REST": {
+ "endpoint": "http://localhost/api/"
+ }
+ }
+ // ..
+}
+```
diff --git a/mkdocs.yml b/mkdocs.yml
index ce8dbc980..a45fb5123 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,31 +1,61 @@
site_name: CodeceptJS
+theme:
+ name: mkdocs
theme_dir: layout
repo_url: https://github.com/codeception/codeceptjs/
pages:
- Index: 'index.md'
-- Quickstart: 'quickstart.md'
-- Guides:
- - 'Installation': 'installation.md'
+- Quickstart:
+ - 'Overview': 'quickstart/quickstart.md'
+ - 'Installation': 'quickstart/installation.md'
+ - 'Puppeteer': 'quickstart/puppeteer.md'
+ - 'WebDriver': 'quickstart/selenium.md'
+ - 'Protractor': 'quickstart/protractor.md'
+ - 'Nightmare': 'quickstart/nightmare.md'
+- Concepts:
- 'Basics': 'basics.md'
- 'Acceptance Testing': 'acceptance.md'
- - 'AngularJS Testing': 'angular.md'
- - 'Nightmare Testing': 'nightmare.md'
+ - 'BDD Testing': 'bdd.md'
+ - 'Test Lifecycle': 'lifecycle.md'
+ - 'Locators': 'locators.md'
+ - 'Debugging': 'debugging.md'
- 'Helpers': 'helpers.md'
- 'Page Objects': 'pageobjects.md'
- - 'Hooks': 'hooks.md'
+ - 'Data Driven Tests': 'datadriven.md'
+ - 'Retries': 'retries.md'
+ - 'Multiple Sessions': 'sessions.md'
+- Guides:
+ - 'Puppeteer Testing': 'puppeteer.md'
+ - 'AngularJS Testing': 'angular.md'
+ - 'Nightmare Testing': 'nightmare.md'
+ - 'Mobile Testing': 'mobile.md'
+ - 'Data Management': 'data.md'
+ - 'Frames': 'frames.md'
+ - 'Drag and Drop': 'drag-drop.md'
+ - 'Multiple Browsers': 'multi.md'
- 'Advanced Usage': 'advanced.md'
- Helpers:
- - 'WebDriverIO': 'helpers/WebDriverIO.md'
+ - 'What is a Helper?': 'what-is-helper.md'
+ - 'WebDriver': 'helpers/WebDriver.md'
- 'Protractor': 'helpers/Protractor.md'
- 'SeleniumWebdriver': 'helpers/SeleniumWebdriver.md'
+ - 'Puppeteer': 'helpers/Puppeteer.md'
- 'Nightmare': 'helpers/Nightmare.md'
+ - 'Appium': 'helpers/Appium.md'
+ - 'REST': 'helpers/REST.md'
+ - 'ApiDataFactory': 'helpers/ApiDataFactory.md'
- 'FileSystem': 'helpers/FileSystem.md'
+ - 'Reports': 'helpers/Mochawesome.md'
- Reference:
+ - 'Installation': 'installation.md'
- 'Commands': 'commands.md'
- 'Configuration': 'configuration.md'
- 'Reports': 'reports.md'
- 'Translation': 'translation.md'
+ - 'Plugins': 'plugins.md'
- 'Docker': 'docker.md'
+ - 'Hooks': 'hooks.md'
+ - 'API': 'api.md'
- Releases: 'changelog.md'
copyright: Created by CodeceptJS Team
google_analytics: ['UA-30075781-3','auto']
\ No newline at end of file