diff --git a/.circleci/build.sh b/.circleci/build.sh
new file mode 100755
index 000000000..a749511a1
--- /dev/null
+++ b/.circleci/build.sh
@@ -0,0 +1,5 @@
+cd test
+
+docker-compose build
+docker-compose pull php selenium.chrome
+
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 000000000..b27d52d24
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,50 @@
+version: 2
+
+defaults: &defaults
+ machine:
+ image: circleci/classic:201710-02
+ docker_layer_caching: false
+ steps:
+ - checkout
+ - run: .circleci/build.sh
+ - run:
+ command: docker-compose run --rm test-unit
+ working_directory: test
+ when: always
+ - run:
+ command: docker-compose run --rm test-rest
+ working_directory: test
+ when: always
+ - run:
+ command: docker-compose run --rm test-graphql
+ working_directory: test
+ when: always
+ - run:
+ command: docker-compose run --rm test-acceptance.webdriverio
+ working_directory: test
+ when: always
+ - run:
+ command: docker-compose run --rm test-acceptance.nightmare
+ working_directory: test
+ when: always
+ - run:
+ command: docker-compose run --rm test-acceptance.puppeteer
+ working_directory: test
+ when: always
+ - run:
+ command: docker-compose run --rm test-acceptance.protractor
+ working_directory: test
+ when: always
+
+jobs:
+ docker:
+ <<: *defaults
+ environment:
+ - NODE_VERSION: 12.8.0
+
+workflows:
+ version: 2
+
+ test_all:
+ jobs:
+ - docker
diff --git a/.circleci/test.sh b/.circleci/test.sh
new file mode 100755
index 000000000..e08fcea74
--- /dev/null
+++ b/.circleci/test.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+set -e
+
+cd test
+
+docker-compose run --rm test-unit &&
+docker-compose run --rm test-rest &&
+docker-compose run --rm test-acceptance.webdriverio &&
+docker-compose run --rm test-acceptance.nightmare &&
+docker-compose run --rm test-acceptance.puppeteer &&
+docker-compose run --rm test-acceptance.protractor
\ No newline at end of file
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 000000000..efb3112f1
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,2 @@
+**/node_modules
+test
\ No newline at end of file
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 000000000..65b969be4
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+test/data/output
diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index f01b199b7..000000000
--- a/.eslintrc
+++ /dev/null
@@ -1,127 +0,0 @@
-{
- "extends": "eslint:recommended",
- "env": {
- "node": true,
- "mocha": true,
- "es6": true
- },
- "ecmaFeatures": {
- "jsx": true,
- "modules": true
- },
- "rules": {
- "array-bracket-spacing": [
- 2,
- "never"
- ],
- "brace-style": [
- 2,
- "1tbs"
- ],
- "consistent-return": 0,
- "indent": [
- 2,
- 2
- ],
- "no-multiple-empty-lines": [
- 2,
- {
- "max": 2
- }
- ],
- "no-use-before-define": [
- 2,
- "nofunc"
- ],
- "one-var": [
- 2,
- "never"
- ],
- "quote-props": [
- 2,
- "as-needed"
- ],
- "space-after-keywords": [
- 2,
- "always"
- ],
- "space-before-function-paren": [
- 2,
- {
- "anonymous": "always",
- "named": "never"
- }
- ],
- "space-in-parens": [
- 2,
- "never"
- ],
- "curly": [
- 2,
- "multi-line"
- ],
- "eol-last": 2,
- "key-spacing": [
- 2,
- {
- "beforeColon": false,
- "afterColon": true
- }
- ],
- "no-with": 2,
- "space-infix-ops": 2,
- "dot-notation": [
- 2,
- {
- "allowKeywords": true
- }
- ],
- "eqeqeq": 2,
- "no-alert": 2,
- "no-caller": 2,
- "no-empty-label": 2,
- "no-extend-native": 2,
- "no-extra-bind": 2,
- "no-implied-eval": 2,
- "no-iterator": 2,
- "no-label-var": 2,
- "no-labels": 2,
- "no-lone-blocks": 2,
- "no-loop-func": 2,
- "no-multi-spaces": 2,
- "no-multi-str": 2,
- "no-native-reassign": 2,
- "no-new": 2,
- "no-new-func": 2,
- "no-new-wrappers": 2,
- "no-octal-escape": 2,
- "no-proto": 2,
- "no-return-assign": 2,
- "no-script-url": 2,
- "no-sequences": 2,
- "no-unused-expressions": 2,
- "yoda": 2,
- "no-shadow": 2,
- "no-shadow-restricted-names": 2,
- "no-undef-init": 2,
- "camelcase": 2,
- "comma-spacing": 2,
- "new-cap": 2,
- "new-parens": 2,
- "no-array-constructor": 2,
- "no-extra-parens": 2,
- "no-new-object": 2,
- "no-spaced-func": 2,
- "no-trailing-spaces": 2,
- "no-underscore-dangle": 2,
- "semi": 2,
- "semi-spacing": [
- 2,
- {
- "before": false,
- "after": true
- }
- ],
- "space-return-throw-case": 2
- }
-}
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 000000000..33d9c6e9a
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,43 @@
+{
+ "extends": "airbnb-base",
+ "env": {
+ "node": true
+ },
+ "rules": {
+ "func-names": 0,
+ "no-use-before-define": 0,
+ "no-unused-vars": 0,
+ "no-underscore-dangle": 0,
+ "no-undef": 0,
+ "prefer-destructuring": 0,
+ "no-param-reassign": 0,
+ "max-len": 0,
+ "camelcase": 0,
+ "no-shadow": 0,
+ "consistent-return": 0,
+ "no-console": 0,
+ "global-require": 0,
+ "class-methods-use-this": 0,
+ "no-plusplus": 0,
+ "no-return-assign": 0,
+ "prefer-rest-params": 0,
+ "no-useless-escape": 0,
+ "no-restricted-syntax": 0,
+ "no-unused-expressions": 0,
+ "guard-for-in": 0,
+ "no-multi-assign": 0,
+ "require-yield": 0,
+ "prefer-spread": 0,
+ "import/no-dynamic-require": 0,
+ "no-continue": 0,
+ "no-mixed-operators": 0,
+ "default-case": 0,
+ "import/no-extraneous-dependencies": 0,
+ "no-cond-assign": 0,
+ "import/no-unresolved": 0,
+ "no-await-in-loop": 0,
+ "arrow-body-style": 0,
+ "no-loop-func": 0,
+ "arrow-parens": 0
+ }
+}
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..c636246c4
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,45 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at team@codeception.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 000000000..fa9f83b01
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,241 @@
+# Contributing
+
+Thanks for getting here. If you have a good will to improve CodeceptJS we are always glad to help. Ask questions, raise issues, ping in Twitter.
+
+To start you need:
+
+1. Fork the repo.
+2. Run `npm install` to install all required libraries
+3. Do the changes.
+4. Add/Update Test (if possible)
+5. Update documentation
+6. Commit and Push to your fork
+7. Make Pull Request
+
+To run codeceptjs from this repo use:
+
+```
+node bin/codecept.js
+```
+
+To run examples:
+
+```
+node bin/codecept.js run -c examples
+```
+
+
+Depending on a type of a change you should do the following.
+
+## Helpers
+
+Please keep in mind that CodeceptJS have **unified API** for WebDriverIO, Appium, Protractor, Nightmare, Puppeteer, TestCafe. Tests written using those helpers should be compatible at syntax level. However, some of helpers may contain unique methods. That happens. If, for instance, WebDriverIO has method XXX and Nightmare doesn't, you can implement XXX inside Nightmare using the same method signature.
+
+### Updating a WebDriverIO | Nightmare
+
+*Whenever a new method or new behavior is added it should be documented in a docblock. Valid JS-example is required! Do **not edit** `docs/helpers/`, those files are generated from docblocks in corresponding helpers! *
+
+Working test is highly appreciated. To run the test suite you need:
+
+* selenium server + chromedriver
+* PHP installed
+
+To launch PHP demo application run:
+
+```sh
+php -S 127.0.0.1:8000 -t test/data/app
+```
+
+Execute test suite:
+
+```sh
+mocha test/helper/WebDriverIO_test.js
+mocha test/helper/Puppeteer_test.js
+mocha test/helper/Nightmare_test.js
+```
+
+Use `--grep` to execute tests only for changed parts.
+
+If you need to add new HTML page for a test, please create new `.php` file in to `tests/data/app/view/form`:
+
+Adding `myexample` page:
+
+```sh
+tests/data/app/view/form/myexample.php
+```
+
+Then is should be accessible at:
+
+```sh
+http://localhost:8000/form/myexample
+```
+
+### Updating Protractor
+
+*Whenever a new method or new behavior is added it should be documented in a docblock. Valid JS-example is required! Do **not edit** `docs/helpers/`, those files are generated from docblocks in corresponding helpers! *
+
+Protractor helper is based on [Protractor library](http://www.protractortest.org)
+
+In case you do Protractor-specific change, please add a test:To run the test suite you need:
+
+* selenium server + chromedriver
+
+Demo application is located at: [http://davertmik.github.io/angular-demo-app](http://davertmik.github.io/angular-demo-app)
+
+### Updating REST | ApiDataFactory
+
+*Whenever a new method or new behavior is added it should be documented in a docblock. Valid JS-example is required!*
+
+Adding a test is highly appreciated.
+
+Start JSON server to run tests:
+
+```sh
+npm run json-server
+```
+
+Edit a test at `test/rest/REST_test.js` or `test/rest/ApiDataFactory_test.js`
+
+## Appium
+
+*Whenever a new method or new behavior is added it should be documented in a docblock. Valid JS-example is required! Do **not edit** `docs/helpers/`, those files are generated from docblocks in corresponding helpers! *
+
+It is recommended to run mobile tests on CI.
+So do the changes, make pull request, see the CI status.
+Appium tests are executed at **Semaphore CI**.
+
+## Core Changes
+
+Before applying any Core changes please raise an issue to discuss that change with core team.
+Please try to add corresponding testcase to runner or unit.
+
+## Documentation
+
+Documentation is stored in `/docs` directory in markdown format.
+
+**Documentation for helpers is a part of a source code**.
+
+> **Whenever you need to update docs for a helper do it inside a .js file.**
+
+After you updated docblock in JS file, generate markdown files with next command:
+
+```
+npm run docs
+```
+
+Documentation parts can be shared accross helpers. Those parts are located in `docs/webapi/*.mustache`. Inside a docblock those files can be included like this:
+
+```js
+ /**
+ * {{> click }}
+ */
+ click() {
+ // ...
+ }
+```
+
+## Typings
+
+Typings is generated in `typings/` directory via `jsdoc`
+
+After you updated docblock in JS file, generate typing files with next command:
+
+```
+npm run def
+```
+
+## Testing
+
+Whenever you implemented a feature/bugfix
+
+Run unit tests:
+
+```sh
+mocha test/unit
+```
+
+Run general tests:
+
+```sh
+mocha test/runner
+```
+
+### Running tests in Dockerized environment
+
+Instead of manually running php, json_server and selenium for before tests you
+can use `docker-compose` to run those automatically.
+You can find `docker-compose.yml` file in `test` directory and run all commands
+from this directory. Currently we provide following commands to run tests with
+respective dependencies:
+
+#### Run unit tests
+
+```sh
+docker-compose run --rm test-unit
+```
+
+#### Run helper tests
+
+```sh
+docker-compose run --rm test-helpers
+
+# or pass path to helper test to run specific helper,
+# for example to run only WebDriverIO tests:
+docker-compose run --rm test-helpers test/helper/WebDriverIO_test.js
+
+# Or to run only rest and ApiDataFactory tests
+docker-compose run --rm test-helpers test/rest
+```
+
+#### Run acceptance tests
+
+To that we provide three separate services respectively for WebDriverIO, Nightmare, Puppeteer and
+Protractor tests:
+
+```sh
+docker-compose run --rm test-acceptance.webdriverio
+docker-compose run --rm test-acceptance.nightmare
+docker-compose run --rm test-acceptance.puppeteer
+docker-compose run --rm test-acceptance.protractor
+```
+
+#### Running against specific Node version
+
+By default dockerized tests are run against node 12.10.0, you can run it against
+specific version as long as there is Docker container available for such
+version. To do that you need to build codecept's Docker image prior to running
+tests and pass `NODE_VERSION` as build argument.
+
+For example to prepare `test-helpers` containers based on node 9.4.0:
+
+```sh
+docker-compose build --build-arg NODE_VERSION=9.4.0 test-helpers
+```
+
+And now every command based on `test-helpers` service will use node 9.4.0. The
+same argument can be passed when building unit and acceptance tests services.
+
+### CI flow
+We're currently using bunch of CI services to build and test codecept in
+different environments. Here's short summary of what are differences between
+separate services
+
+#### TravisCI
+Travis CI uses runs tests against Node 8 and Node 9. In total it uses 8 jobs to
+build each helper against both Node versions. For every job it runs unit tests
+first, then `ApiDataFactory` and `REST` tests present in `test/rest` directory.
+Finally if those pass we run specific helper tests found in `test/helper`
+directory. It doesn't run acceptance tests.
+Config is present in `.travis.yml` file.
+
+#### CircleCI
+Here we use CodeceptJS docker image to build and execute tests inside it. We
+start with building Docker container based on Dockerfile present in main project
+directory. Then we run (in this order) unit tests, all helpers present in
+`test/helpers`, then we go with `test/rest` directory and finally if everything
+passed so far it executes acceptance tests. For easier maintenance and local
+debugging CircleCI uses `docker-compose.yml` file from `test` directory.
+You can find Circle config in `.circleci` directory.
+
+#### Semaphore
+Currently Semaphore runs only Appium helper tests.
diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
similarity index 72%
rename from ISSUE_TEMPLATE.md
rename to .github/ISSUE_TEMPLATE.md
index ebfaa83f4..5c6181a83 100644
--- a/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -7,19 +7,21 @@
```bash
# paste output here
```
+
> Provide test source code if related
-```php
+```js
// paste test
```
+
### Details
-* CodeceptJS version:
+* CodeceptJS version:
* NodeJS Version:
* Operating System:
-* Protractor || WebDriverIO || Nightmare version (if related)
+* puppeteer || webdriverio || protractor || testcafe version (if related)
* Configuration file:
```js
-# paste suite config here
+# paste config here
```
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..194360e18
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,46 @@
+## Motivation/Description of the PR
+- Description of this PR, which problem it solves
+- Resolves #issueId (if applicable).
+
+Applicable helpers:
+
+- [ ] WebDriver
+- [ ] Puppeteer
+- [ ] Nightmare
+- [ ] REST
+- [ ] FileHelper
+- [ ] Appium
+- [ ] Protractor
+- [ ] TestCafe
+- [ ] Playwright
+
+Applicable plugins:
+
+- [ ] allure
+- [ ] autoDelay
+- [ ] autoLogin
+- [ ] customLocator
+- [ ] pauseOnFail
+- [ ] puppeteerCoverage
+- [ ] retryFailedStep
+- [ ] screenshotOnFail
+- [ ] selenoid
+- [ ] stepByStepReport
+- [ ] wdio
+
+## Type of change
+
+- [ ] :fire: Breaking changes
+- [ ] :rocket: New functionality
+- [ ] :bug: Bug fix
+- [ ] :clipboard: Documentation changes/updates
+- [ ] :hotsprings: Hot fix
+- [ ] :hammer: Markdown files fix - not related to source code
+- [ ] :nail_care: Polish code
+
+## Checklist:
+
+- [ ] Tests have been added
+- [ ] Documentation has been added (Run `npm run docs`)
+- [ ] Lint checking (Run `npm run lint`)
+- [ ] Local tests are passed (Run `npm test`)
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
new file mode 100644
index 000000000..cea8185a5
--- /dev/null
+++ b/.github/workflows/check.yml
@@ -0,0 +1,20 @@
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ name: Check Tests
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - uses: testomatio/check-tests@master
+ with:
+ framework: mocha
+ tests: "./test/**/*_test.js"
+ token: ${{ secrets.GITHUB_TOKEN }}
+ has-tests-label: true
+ comment-on-empty: true
+ github-pat: ${{ secrets.GH_PAT }}
+ enable-documentation: true
+ documentation-branch: "master"
diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml
new file mode 100644
index 000000000..df5599968
--- /dev/null
+++ b/.github/workflows/playwright.yml
@@ -0,0 +1,47 @@
+name: Playwright Tests
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+
+env:
+ CI: true
+ # Force terminal colors. @see https://www.npmjs.com/package/colors
+ FORCE_COLOR: 1
+
+jobs:
+ build:
+
+ runs-on: ubuntu-18.04
+
+ strategy:
+ matrix:
+ node-version: [12.x]
+
+ steps:
+ - uses: actions/checkout@v1
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - uses: microsoft/playwright-github-action@v1
+ - name: install required packages
+ run: |
+ sudo apt-get install php
+ - name: npm install
+ run: |
+ npm install
+ - name: start a server
+ run: "php -S 127.0.0.1:8000 -t test/data/app &"
+ - name: run chromium tests
+ run: "./bin/codecept.js run -c test/acceptance/codecept.Playwright.js --grep @Playwright --debug"
+ - name: run firefox tests
+ run: "BROWSER=firefox node ./bin/codecept.js run -c test/acceptance/codecept.Playwright.js --grep @Playwright --debug"
+ - name: run webkit tests
+ run: "BROWSER=webkit node ./bin/codecept.js run -c test/acceptance/codecept.Playwright.js --grep @Playwright --debug"
+ - name: run unit tests
+ run: ./node_modules/.bin/mocha test/helper/Playwright_test.js
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 000000000..5818c4c92
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,21 @@
+name: Run Unit tests
+
+on: [push]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-18.04
+
+ strategy:
+ matrix:
+ node-version: [10.x, 12.x]
+
+ steps:
+ - uses: actions/checkout@v1
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: npm install
+ - run: npm test
diff --git a/.gitignore b/.gitignore
index 40f2015d9..89adfd139 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,21 @@ coverage
.vscode
coverage
site
+docs/.vuepress/dist
+docs/node_modules
+docs/wiki
+website
.idea
docs/build
test/data/output
-examples/output
\ No newline at end of file
+test/acceptance/output
+examples/output
+examples/selenoid-example/output
+test/data/app/db
+test/data/sandbox/steps.d.ts
+testpullfilecache*
+.DS_Store
+package-lock.json
+yarn.lock
+/.vs
+typings/types.d.ts
diff --git a/.hound.yml b/.hound.yml
new file mode 100644
index 000000000..6728a4cba
--- /dev/null
+++ b/.hound.yml
@@ -0,0 +1,3 @@
+eslint:
+ enabled: true
+ config_file: .eslintrc.json
\ No newline at end of file
diff --git a/.markdownlint.json b/.markdownlint.json
new file mode 100644
index 000000000..73029d818
--- /dev/null
+++ b/.markdownlint.json
@@ -0,0 +1,19 @@
+{
+ "MD007": {
+ "indent": 4
+ },
+ "MD013": false,
+ "MD026": {
+ "punctuation": ".,;:!"
+ },
+ "MD029": {
+ "style": "ordered"
+ },
+ "MD030": {
+ "ul_multi": 1,
+ "ul_single": 1,
+ "ol_single": 2,
+ "ol_multi": 2
+ },
+ "MD036": false
+}
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 15821580a..a1997238f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,38 +1,32 @@
language: node_js
node_js:
- - '4.3'
- - '6.9.5'
- - '7'
-
-
+- 12
sudo: required
dist: trusty
-
env:
- - HELPER=Protractor
+ global:
+ - secure: vLPyF/U+KhmWAXMkcrYFben6Qo5Tsk9nExbb/YTxCCqtpu5FlCcKZ0h/7OXJT9sXR7t8dmz564VbAtbhazPU+2FdpxIoR/D6OUeZa1WhyB5GGfpfHmfIe1hQTsZg0B0zGrrpcLBeaTA1E7+0lBhIKj9S1FoApa6xfP21bju+IddpD881m0bdF/2gEiBrabWHoQieWLNgS4EzUI5IcOknz4bk3nx6ztldJOokwTqUy2RgtVbMkJf0v6LbBOxT5uCwlLYxllDwY6fIatPP7Gol5V2fxMYhp4k/QSeULy81EJBpVhW0Bw5FfGBBVnqk495fhCjRNbjwzcs2zz2dD1i99KeIFhfKYQsfto7odHbt0kasYgaQQUZEZsbY6ScYMDXnzprTCotolmPXJmqu0rHnUfa2ZZxl9/jNis1IoCdwsvJ+cemL13fw9llFvnMGtmqDc9ltjzKoRfi8rpUH5x6EbnUE6vdr0RDA+D3mUbFr2kxlMwQPTpujnxOghpuDnDc/2CGe17uklssw2g2vMxdIuiqxXvKkeN0xBddtlbUx2PwRrecjCmv7RE13j+ERsIysDQUkTMnXTWBumtVGmdxZpFhxD7wwmVFi3qjq4FGyO3f8alnfYOBspPhLgC2PTJGS/X23C9LC08tFl6MpeHD97HUaW6bx+ObI2/0jBsDXB3k=
+ - secure: OlLkzBUwlRFIa5xDWEs/It6ofSfC+pXRVt17kTyox8beH5qu5Ks3/Zwa48YMqHKnbNHI7hiRBO2YfsJgjYJoQ5/ovKPa3rvffNXdKeDZpt+lQqlhjJYpgp0pNgck45RKnFj1pKpQCVG6dWWcT59Gi8NoI8AsAVCVgFtO8McfV8qbks6G2UP0GdFR5s6tRyZTjfCVmMNtJX9veYuibwoiwRyFhh1FY+sw5BvAONSBdOWmcK7RdDm7IE+Oitzn3bRZnC6sgLNpy6qhncED/pbn4GFD5MRlu0UkDGDfXldsOyjOtqdaN5WbOGdhevaYgr/5VvSeMbO7fITlDXbhz9pViogl6fnxj0zELZvG6b6H7nAVV29uzHP4jofocP41h33rvYnQUTfNHN8HIRN4LVfekN2I27GDO+J1QFiWNN/36nhsRH9tWPwSNC2f9QLIf6OrD60FVUIMlQrFHqyrO4KZBZkRsGMgYzsa5XmGOGUATUBrmQVTynNQc+yhniJd4Q8LwwmXMDWNeoeg5eh0TFgERVDlkQ8tPaWOXmpHi6BL4JZlGz275SDWgZH4bnH2B1RzO1qcGN905vIo5snX8LwZbxSfXrt+4WP3jOi+1i8ZrFwACk7jlovJiJquQuZQ5dL7C9rBwpAWB8YjgOKNikDWvUrVnYGS/gLwrdN7+pRiims=
+ matrix:
- HELPER=Nightmare
- - HELPER=SeleniumWebdriver
- - HELPER=WebDriverIO
-
+ - HELPER=Puppeteer
+ - HELPER=ProtractorWeb
+ - HELPER=WebDriver
+ - HELPER=TestCafe
addons:
apt:
packages:
- - php5-cli
-
+ - php5-cli
services:
- - docker
-
+- docker
before_install:
- - docker pull selenium/standalone-chrome:2.53.0
-
+- docker pull selenium/standalone-chrome:3.141.59-oxygen
before_script:
- - docker run -d --net=host selenium/standalone-chrome:2.53.0
- - export DISPLAY=:99.0
- - sh -e /etc/init.d/xvfb start
- - chmod -R 777 test/data
- - "php -S 127.0.0.1:8000 -t test/data/app >/dev/null 2>&1 &"
- - sleep 10
-
+- docker run -d --net=host --shm-size=2g selenium/standalone-chrome:3.141.59-oxygen
+- export DBUS_SESSION_BUS_ADDRESS=/dev/null
+- export DISPLAY=:99.0
+- sleep 3
+- chmod -R 777 test/data
+- php -S 127.0.0.1:8000 -t test/data/app >/dev/null 2>&1 &
script:
- - gulp test
- - '[[ "$TRAVIS_NODE_VERSION" == "4.3" ]] || ./node_modules/.bin/mocha test/helper/${HELPER}_test.js'
\ No newline at end of file
+- mocha test/helper/${HELPER}_test.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67f822360..841870af0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,1367 @@
+## 2.6.11
+
+* [Playwright] Playwright 1.4 compatibility
+* [Playwright] Added `ignoreHTTPSErrors` config option (default: false). See #2566 by gurjeetbains
+* Added French translation by @vimar
+* [WebDriver] Updated `dragSlider` to work in WebDriver W3C protocol. Fixes #2557 by suniljaiswal01
+
+## 2.6.10
+
+* Fixed saving options for suite via `Feature('title', {key: value})` by @Diokuz. See #2553 and [Docs](https://codecept.io/advanced/#dynamic-configuration)
+
+## 2.6.9
+
+* [Puppeteer][Playwright] SessionStorage is now cleared in after hook. See #2524
+* When helper load failed the error stack is now logged by @SkReD. See #2541
+* Small documentation fixes.
+
+## 2.6.8
+
+* [WebDriver][Protractor][Playwright][Puppeteer][Nightmare] `saveElementScreenshot` method added to make screenshot of an element. By @suniljaiswal01
+* [Playwright][Puppeteer] Added `type` method to type a text using keyboard with an optional delay.
+* [WebDriver] Added optional `delay` argument to `type` method to slow down typing.
+* [Puppeteer] Fixed `amOnPage` freeze when `getPageTimeout` is 0"; set 30 sec as default timeout by @Vorobeyko.
+* Fixed printing step with null argument in custom helper by @sjana-aj. See #2494
+* Fix missing screenshot on failure when REST helper is in use #2513 by @PeterNgTr
+* Improve error logging in the `screenshotOnFail` plugin #2512 by @pablopaul
+
+## 2.6.7
+
+* Add REST helper into `standardActingHelpers` array #2474 by @PeterNgTr
+* Add missing `--invert` option for `run-workers` command #2504 by @pablopaul
+* [WebDriver] Introduce `forceRightClick` method #2485 bylsuniljaiswal01
+* [Playwright] Fix `setCookie` method #2491 by @bmbarker90
+* [TypeScript] Update compilerOptions.target to es2017 #2483 by @shanplourde
+* [Mocha] Honor reporter configuration #2465 by @trinhpham
+
+## 2.6.6
+
+* Puppeteer 4.0 support. Important: MockRequest helper won't work with Puppeter > 3.3
+* Added `xFeature` and `Feature.skip` to skip all tests in a suite. By @Georgegriff
+* [Appium] Fixed #2428 Android native locator support by @idxn
+* [WebDriver] Fixed `waitNumberOfVisibleElements` to actually filter visible elements. By @ilangv
+* [Puppeteer] Fixed handling error which is not an Error object. Fixes `cannot read property indexOf of undefined` error. Fix #2436 by @Georgegriff
+* [Puppeteer] Print error on page crash by @Georgegriff
+
+## 2.6.5
+
+* Added `test.skipped` event to run-workers, fixing allure reports with skipped tests in workers #2391. Fix #2387 by @koushikmohan1996
+* [Playwright] Fixed calling `waitFor*` methods with custom locators #2314. Fix #2389 by @Georgegriff
+
+## 2.6.4
+
+* [Playwright] **Playwright 1.0 support** by @Georgegriff.
+
+## 2.6.3
+
+* [stepByStepReport plugin] Fixed when using plugin with BeforeSuite. Fixes #2337 by @mirao
+* [allure plugin] Fixed reporting of tests skipped by failure in before hook. Refer to #2349 & #2354. Fix by @koushikmohan1996
+
+## 2.6.2
+
+* [WebDriver][Puppeteer] Added `forceClick` method to emulate click event instead of using native events.
+* [Playwright] Updated to 0.14
+* [Puppeteer] Updated to Puppeteer v3.0
+* [wdio] Fixed undefined output directory for wdio plugns. Fix By @PeterNgTr
+* [Playwright] Introduced `handleDownloads` method to download file. Please note, this method has slightly different API than the same one in Puppeteer.
+* [allure] Fixed undefined output directory for allure plugin on using custom runner. Fix by @charliepradeep
+* [WebDriver] Fixed `waitForEnabled` fix for webdriver 6. Fix by @dsharapkou
+* Workers: Fixed negative failure result if use scenario with the same names. Fix by @Vorobeyko
+* [MockRequest] Updated documentation to match new helper version
+* Fixed: skipped tests are not reported if a suite failed in `before`. Refer #2349 & #2354. Fix by @koushikmohan1996
+
+## 2.6.1
+
+* [screenshotOnFail plugin] Fixed saving screenshot of active session.
+* [screenshotOnFail plugin] Fix issue #2301 when having the flag `uniqueScreenshotNames`=true results in `undefined` in screenshot file name by @PeterNgTr
+* [WebDriver] Fixed `waitForElement` not applying the optional second argument to override the default timeout in webdriverio 6. Fix by @Mooksc
+* [WebDriver] Updated `waitUntil` method which is used by all of the wait* functions. This updates the `waitForElement` by the same convention used to update `waitForVisible` and `waitInUrl` to be compatible with both WebDriverIO v5 & v6. See #2313 by @Mooksc
+
+## 2.6.0
+
+* **[Playwright] Updated to Playwright 0.12** by @Georgegriff.
+
+Upgrade playwright to ^0.12:
+
+```
+npm i playwright@^0.12 --save
+```
+
+[Notable changes](https://github.com/microsoft/playwright/releases/tag/v0.12.0):
+ * Fixed opening two browsers on start
+ * `executeScript` - passed function now accepts only one argument. Pass in objects or arrays if you need multtple arguments:
+```js
+// Old style, does not work anymore:
+I.executeScript((x, y) => x + y, x, y);
+// New style, passing an object:
+I.executeScript(({x, y}) => x + y, {x, y});
+```
+ * `click` - automatically waits for element to become clickable (visible, not animated) and waits for navigation.
+ * `clickLink` - deprecated
+ * `waitForClickable` - deprecated
+ * `forceClick` - added
+ * Added support for custom locators. See #2277
+ * Introduced [device emulation](/playwright/#device-emulation):
+ * globally via `emulate` config option
+ * per session
+
+**[WebDriver] Updated to webdriverio v6** by @PeterNgTr.
+
+Read [release notes](https://webdriver.io/blog/2020/03/26/webdriverio-v6-released.html), then
+upgrade webdriverio to ^6.0:
+
+```
+npm i webdriverio@^6.0 --save
+```
+*(webdriverio v5 support is deprecated and will be removed in CodeceptJS 3.0)*
+
+[WebDriver] Introduced [Shadow DOM support](/shadow) by @gkushang
+
+```js
+I.click({ shadow: ['my-app', 'recipe-hello', 'button'] });
+```
+
+* **Fixed parallel execution of `run-workers` for Gherkin** scenarios by @koushikmohan1996
+* [MockRequest] Updated and **moved to [standalone package](https://github.com/codecept-js/mock-request)**:
+ * full support for record/replay mode for Puppeteer
+ * added `mockServer` method to use flexible PollyJS API to define mocks
+ * fixed stale browser screen in record mode.
+* [Playwright] Added support on for `screenshotOnFail` plugin by @amonkc
+* Gherkin improvement: setting different tags per examples. See #2208 by @acuper
+* [TestCafe] Updated `click` to take first visible element. Fixes #2226 by @theTainted
+* [Puppeteer][WebDriver] Updated `waitForClickable` method to check for element overlapping. See #2261 by @PiQx
+* [Puppeteer] Dropped `puppeteer-firefox` support, as Puppeteer supports Firefox natively.
+* [REST] Rrespect Content-Type header. See #2262 by @pmarshall-legacy
+* [allure plugin] Fixes BeforeSuite failures in allure reports. See #2248 by @Georgegriff
+* [WebDriver][Puppeteer][Playwright] A screenshot of for an active session is saved in multi-session mode. See #2253 by @ChexWarrior
+* Fixed `--profile` option by @pablopaul. Profile value to be passed into `run-multiple` and `run-workers`:
+
+```
+npx codecept run-workers 2 --profile firefox
+```
+
+Value is available at `process.env.profile` (previously `process.profile`). See #2302. Fixes #1968 #1315
+
+* [commentStep Plugin introduced](/plugins#commentstep). Allows to annotate logical parts of a test:
+
+```js
+__`Given`;
+I.amOnPage('/profile')
+
+__`When`;
+I.click('Logout');
+
+__`Then`;
+I.see('You are logged out');
+```
+
+## 2.5.0
+
+* **Experimental: [Playwright](/playwright) helper introduced**.
+
+> [Playwright](https://github.com/microsoft/playwright/) is an alternative to Puppeteer which works very similarly to it but adds cross-browser support with Firefox and Webkit. Until v1.0 Playwright API is not stable but we introduce it to CodeceptJS so you could try it.
+
+* [Puppeteer] Fixed basic auth support when running in multiple sessions. See #2178 by @ian-bartholomew
+* [Puppeteer] Fixed `waitForText` when there is no `body` element on page (redirect). See #2181 by @Vorobeyko
+* [Selenoid plugin] Fixed overriding current capabilities by adding deepMerge. Fixes #2183 by @koushikmohan1996
+* Added types for `Scenario.todo` by @Vorobeyko
+* Added types for Mocha by @Vorobeyko. Fixed typing conflicts with Jest
+* [FileSystem] Added methods by @nitschSB
+ * `waitForFile`
+ * `seeFileContentsEqualReferenceFile`
+* Added `--colors` option to `run` and `run-multiple` so you force colored output in dockerized environment. See #2189 by @mirao
+* [WebDriver] Added `type` command to enter value without focusing on a field. See #2198 by @xMutaGenx
+* Fixed `codeceptjs gt` command to respect config pattern for tests. See #2200 and #2204 by @matheo
+
+
+## 2.4.3
+
+* Hotfix for interactive pause
+
+## 2.4.2
+
+* **Interactive pause improvements** by @koushikmohan1996
+ * allows using in page objects and variables: `pause({ loginPage, a })`
+ * enables custom commands inside pause with `=>` prefix: `=> loginPage.open()`
+* [Selenoid plugin](/plugins#selenoid) added by by @koushikmohan1996
+ * uses Selenoid to launch browsers inside Docker containers
+ * automatically **records videos** and attaches them to allure reports
+ * can delete videos for successful tests
+ * can automatically pull in and start Selenoid containers
+ * works with WebDriver helper
+* Avoid failiure report on successful retry in worker by @koushikmohan1996
+* Added translation ability to Scenario, Feature and other context methods by @koushikmohan1996
+ * 📢 Please help us translate context methods to your language! See [italian translation](https://github.com/codeceptjs/CodeceptJS/blob/master/translations/it-IT.js#L3) as an example and send [patches to vocabularies](https://github.com/codeceptjs/CodeceptJS/tree/master/translations).
+* allurePlugin: Added `say` comments to allure reports by @PeterNgTr.
+* Fixed no custom output folder created when executed with run-worker. Fix by @PeterNgTr
+* [Puppeteer] Fixed error description for context element not found. See #2065. Fix by @PeterNgTr
+* [WebDriver] Fixed `waitForClickable` to wait for exact number of seconds by @mirao. Resolves #2166
+* Fixed setting `compilerOptions` in `jsconfig.json` file on init by @PeterNgTr
+* [Filesystem] Added method by @nitschSB
+ * `seeFileContentsEqualReferenceFile`
+ * `waitForFile`
+
+
+## 2.4.1
+
+* [Hotfix] - Add missing lib that prevents codeceptjs from initializing.
+
+## 2.4.0
+
+* Improved setup wizard with `npx codecept init`:
+ * **enabled [retryFailedStep](/plugins/#retryfailedstep) plugin for new setups**.
+ * enabled [@codeceptjs/configure](/configuration/#common-configuration-patterns) to toggle headless/window mode via env variable
+ * creates a new test on init
+ * removed question on "steps file", create it by default.
+* Added [pauseOnFail plugin](/plugins/#pauseonfail). *Sponsored by Paul Vincent Beigang and his book "[Practical End 2 End Testing with CodeceptJS](https://leanpub.com/codeceptjs/)"*.
+* Added [`run-rerun` command](/commands/#run-rerun) to run tests multiple times to detect and fix flaky tests. By @Ilrilan and @Vorobeyko.
+* Added [`Scenario.todo()` to declare tests as pending](/basics#todotest). See #2100 by @Vorobeyko
+* Added support for absolute path for `output` dir. See #2049 by @elukoyanov
+* Fixed error in `npx codecept init` caused by calling `console.print`. See #2071 by @Atinux.
+* [Filesystem] Methods added by @aefluke:
+ * `seeFileNameMatching`
+ * `grabFileNames`
+* [Puppeteer] Fixed grabbing attributes with hyphen by @Holorium
+* [TestCafe] Fixed `grabAttributeFrom` method by @elukoyanov
+* [MockRequest] Added support for [Polly config options](https://netflix.github.io/pollyjs/#/configuration?id=configuration) by @ecrmnn
+* [TestCafe] Fixes exiting with zero code on failure. Fixed #2090 with #2106 by @koushikmohan1996
+* [WebDriver][Puppeteer] Added basicAuth support via config. Example: `basicAuth: {username: 'username', password: 'password'}`. See #1962 by @PeterNgTr
+* [WebDriver][Appium] Added `scrollIntoView` by @pablopaul
+* Fixed #2118: No error stack trace for syntax error by @senthillkumar
+* Added `parse()` method to data table inside Cucumber tests. Use it to obtain rows and hashes for test data. See #2082 by @Sraime
+
+## 2.3.6
+
+* Create better Typescript definition file through JSDoc. By @lemnis
+* `run-workers` now can use glob pattern. By @Ilrilan
+```js
+// Example:
+exports.config = {
+ tests: '{./workers/base_test.workers.js,./workers/test_grep.workers.js}',
+}
+```
+* Added new command `npx codeceptjs info` which print information about your environment and CodeceptJS configs. By @jamesgeorge007
+* Fixed some typos in documantation. By @pablopaul @atomicpages @EricTendian
+* Added PULL_REQUEST template.
+* [Puppeteer][WebDriver] Added `waitForClickable` for waiting clickable element on page.
+* [TestCafe] Added support for remote connection. By @jvdieten
+* [Puppeteer] Fixed `waitForText` XPath context now works correctly. By @Heavik
+* [TestCafe] Fixed `clearField` clear field now awaits TestCafe's promise. By @orihomie
+* [Puppeteer] Fixed fails when executing localStorage on services pages. See #2026
+* Fixed empty tags in test name. See #2038
+
+## 2.3.5
+
+* Set "parse-function" dependency to "5.2.11" to avoid further installation errors.
+
+## 2.3.4
+
+* Fixed installation error "Cannot find module '@babel/runtime/helpers/interopRequireDefault'". The issue came from `parse-function` package. Fixed by @pablopaul.
+* [Puppeteer] Fixed switching to iframe without an ID by @johnyb. See #1974
+* Added `--profile` option to `run-workers` by @orihomie
+* Added a tag definition to `FeatureConfig` and `ScenarioConfig` by @sseliverstov
+
+## 2.3.3
+
+* **[customLocator plugin](#customlocator) introduced**. Adds a locator strategy for special test attributes on elements.
+
+```js
+// when data-test-id is a special test attribute
+// enable and configure plugin to replace this
+I.click({ css: '[data-test-id=register_button]');
+// with this
+I.click('$register_button');
+```
+* [Puppeteer][WebDriver] `pressKey` improvements by @martomo:
+Changed pressKey method to resolve issues and extend functionality.
+ * Did not properly recognize 'Meta' (or 'Command') as modifier key.
+ * Right modifier keys did not work in WebDriver using JsonWireProtocol.
+ * 'Shift' + 'key' combination would not reflect actual keyboard behavior.
+ * Respect sequence with multiple modifier keys passed to pressKey.
+ * Added support to automatic change operation modifier key based on operating system.
+* [Puppeteer][WebDriver] Added `pressKeyUp` and `pressKeyDown` to press and release modifier keys like `Control` or `Shift`. By @martomo.
+* [Puppeteer][WebDriver] Added `grabElementBoundingRect` by @PeterNgTr.
+* [Puppeteer] Fixed speed degradation introduced in #1306 with accessibility locators support. See #1953.
+* Added `Config.addHook` to add a function that will update configuration on load.
+* Started [`@codeceptjs/configure`](https://github.com/codecept-js/configure) package with a collection of common configuration patterns.
+* [TestCafe] port's management removed (left on TestCafe itself) by @orihomie. Fixes #1934.
+* [REST] Headers are no more declared as singleton variable. Fixes #1959
+* Updated Docker image to include run tests in workers with `NUMBER_OF_WORKERS` env variable. By @PeterNgTr.
+
+## 2.3.2
+
+* [Puppeteer] Fixed Puppeteer 1.20 support by @davertmik
+* Fixed `run-workers` to run with complex configs. See #1887 by @nitschSB
+* Added `--suites` option to `run-workers` to split suites by workers (tests of the same suite goes to teh same worker). Thanks @nitschSB.
+* Added a guide on [Email Testing](https://codecept.io/email).
+* [retryFailedStepPlugin] Improved to ignore wait* steps and others. Also added option to ignore this plugin per test bases. See [updated documentation](https://codecept.io/plugins#retryfailedstep). By @davertmik
+* Fixed using PageObjects as classes by @Vorobeyko. See #1896
+* [WebDriver] Fixed opening more than one tab. See #1875 by @jplegoff. Fixes #1874
+* Fixed #1891 when `I.retry()` affected retries of next steps. By @davertmik
+
+## 2.3.1
+
+* [MockRequest] Polly helper was renamed to MockRequest.
+* [MockRequest][WebDriver] [Mocking requests](https://codecept.io/webdriver#mocking-requests) is now available in WebDriver. Thanks @radhey1851
+* [Puppeteer] Ensure configured user agent and/or window size is applied to all pages. See #1862 by @martomo
+* Improve handling of xpath locators with round brackets by @nitschSB. See #1870
+* Use WebDriver capabilities config in wdio plugin. #1869 by @quekshuy
+
+## 2.3.0
+
+
+* **[Parallel testing by workers](https://codecept.io/parallel#parallel-execution-by-workers) introduced** by @VikalpP and @davertmik. Use `run-workers` command as faster and simpler alternative to `run-multiple`. Requires NodeJS v12
+
+```
+# run all tests in parallel using 3 workers
+npx codeceptjs run-workers 3
+```
+* [GraphQL][GraphQLDataFactory] **Helpers for data management over GraphQL** APIs added. By @radhey1851.
+ * Learn how to [use GraphQL helper](https://codecept.io/data#graphql) to access GarphQL API
+ * And how to combine it with [GraphQLDataFactory](https://codecept.io/data#graphql-data-factory) to generate and persist test data.
+* **Updated to use Mocha 6**. See #1802 by @elukoyanov
+* Added `dry-run` command to print steps of test scenarios without running them. Fails to execute scenarios with `grab*` methods or custom code. See #1825 for more details.
+
+```
+npx codeceptjs dry-run
+```
+
+* [Appium] Optimization when clicking, searching for fields by accessibility id. See #1777 by @gagandeepsingh26
+* [TestCafe] Fixed `switchTo` by @KadoBOT
+* [WebDriver] Added geolocation actions by @PeterNgTr
+ * `grabGeoLocation()`
+ * `setGeoLocation()`
+* [Polly] Check typeof arguments for mock requests by @VikalpP. Fixes #1815
+* CLI improvements by @jamesgeorge007
+ * `codeceptjs` command prints list of all available commands
+ * added `codeceptjs -V` flag to print version information
+ * warns on unknown command
+* Added TypeScript files support to `run-multiple` by @z4o4z
+* Fixed element position bug in locator builder. See #1829 by @AnotherAnkor
+* Various TypeScript typings updates by @elukoyanov and @Vorobeyko
+* Added `event.step.comment` event for all comment steps like `I.say` or gherking steps.
+
+## 2.2.1
+
+* [WebDriver] A [dedicated guide](https://codecept.io/webdriver) written.
+* [TestCafe] A [dedicated guide](https://codecept.io/testcafe) written.
+* [Puppeteer] A [chapter on mocking](https://codecept.io/puppeteer#mocking-requests) written
+* [Puppeteer][Nightmare][TestCafe] Window mode is enabled by default on `codeceptjs init`.
+* [TestCafe] Actions implemented by @hubidu
+ * `grabPageScrollPosition`
+ * `scrollPageToTop`
+ * `scrollPageToBottom`
+ * `scrollTo`
+ * `switchTo`
+* Intellisense improvements. Renamed `tsconfig.json` to `jsconfig.json` on init. Fixed autocompletion for Visual Studio Code.
+* [Polly] Take configuration values from Puppeteer. Fix #1766 by @VikalpP
+* [Polly] Add preconditions to check for puppeteer page availability by @VikalpP. Fixes #1767
+* [WebDriver] Use filename for `uploadFile` by @VikalpP. See #1797
+* [Puppeteer] Configure speed of input with `pressKeyDelay` option. By @hubidu
+* Fixed recursive loading of support objects by @davertmik.
+* Fixed support object definitions in steps.d.ts by @johnyb. Fixes #1795
+* Fixed `Data().Scenario().injectDependencies()` is not a function by @andrerleao
+* Fixed crash when using xScenario & Scenario.skip with tag by @VikalpP. Fixes #1751
+* Dynamic configuration of helpers can be performed with async function. See #1786 by @cviejo
+* Added TS definitions for internal objects by @Vorobeyko
+* BDD improvements:
+ * Fix for snippets command with a .feature file that has special characters by @asselin
+ * Fix `--path` option on `gherkin:snippets` command by @asselin. See #1790
+ * Added `--feature` option to `gherkin:snippets` to enable creating snippets for a subset of .feature files. See #1803 by @asselin.
+* Fixed: dynamic configs not reset after test. Fixes #1776 by @cviejo.
+
+## 2.2.0
+
+* **EXPERIMENTAL** [**TestCafe** helper](https://codecept.io/helpers/TestCafe) introduced. TestCafe allows to run cross-browser tests it its own very fast engine. Supports all browsers including mobile. Thanks to @hubidu for implementation! Please test it and send us feedback.
+* [Puppeteer] Mocking requests enabled by introducing [Polly.js helper](https://codecept.io/helpers/Polly). Thanks @VikalpP
+
+```js
+// use Polly & Puppeteer helpers
+I.mockRequest('GET', '/api/users', 200);
+I.mockRequest('POST', '/users', { user: { name: 'fake' }});
+```
+
+* **EXPERIMENTAL** [Puppeteer] [Firefox support](https://codecept.io/helpers/Puppeteer-firefox) introduced by @ngadiyak, see #1740
+* [stepByStepReportPlugin] use md5 hash to generate reports into unique folder. Fix #1744 by @chimurai
+* Interactive pause improvements:
+ * print result of `grab` commands
+ * print message for successful assertions
+* `run-multiple` (parallel execution) improvements:
+ * `bootstrapAll` must be called before creating chunks. #1741 by @Vorobeyko
+ * Bugfix: If value in config has falsy value then multiple config does not overwrite original value. #1756 by @LukoyanovE
+* Fixed hooks broken in 2.1.5 by @Vorobeyko
+* Fix references to support objects when using Dependency Injection. Fix by @johnyb. See #1701
+* Fix dynamic config applied for multiple helpers by @VikalpP #1743
+
+
+## 2.1.5
+
+* **EXPERIMENTAL** [Wix Detox support](https://github.com/codeceptjs/detox-helper) introduced as standalone helper. Provides a faster alternative to Appium for mobile testing.
+* Saving successful commands inside interactive pause into `_output/cli-history` file. By @hubidu
+* Fixed hanging error handler inside scenario. See #1721 by @haily-lgc.
+* Fixed by @Vorobeyko: tests did not fail when an exception was raised in async bootstrap.
+* [WebDriver] Added window control methods by @emmonspired
+ * `grabAllWindowHandles` returns all window handles
+ * `grabCurrentWindowHandle` returns current window handle
+ * `switchToWindow` switched to window by its handle
+* [Appium] Fixed using `host` as configuration by @trinhpham
+* Fixed `run-multiple` command when `tests` config option is undefined (in Gherkin scenarios). By @gkushang.
+* German translation introduced by @hubidu
+
+## 2.1.4
+
+* [WebDriver][Puppeteer][Protractor][Nightmare] A11y locator support introduced by @Holorium. Clickable elements as well as fields can be located by following attributes:
+ * `aria-label`
+ * `title`
+ * `aria-labelledby`
+* [Puppeteer] Added support for React locators.
+ * New [React Guide](https://codecept.io/react) added.
+* [Puppeteer] Deprecated `downloadFile`
+* [Puppeteer] Introduced `handleDownloads` replacing `downloadFile`
+* [puppeteerCoverage plugin] Fixed path already exists error by @seta-tuha.
+* Fixed 'ERROR: ENAMETOOLONG' creating directory names in `run-multiple` with long config. By @artvinn
+* [REST] Fixed url autocompletion combining base and relative paths by @LukoyanovE
+* [Nightmare][Protractor] `uncheckOption` method introduced by @PeterNgTr
+* [autoLogin plugin] Enable to use without `await` by @tsuemura
+* [Puppeteer] Fixed `UnhandledPromiseRejectionWarning: "Execution context was destroyed...` by @adrielcodeco
+* [WebDriver] Keep browser window dimensions when starting a new session by @spiroid
+* Replace Ghekrin plceholders with values in files that combine a scenerio outline and table by @medtoure18.
+* Added Documentation to [locate elements in React Native](https://codecept.io/mobile-react-native-locators) apps. By @DimGun.
+* Adding optional `path` parameter to `bdd:snippets` command to append snippets to a specific file. By @cthorsen31.
+* Added optional `output` parameter to `def` command by @LukoyanovE.
+* [Puppeteer] Added `grabDataFromPerformanceTiming` by @PeterNgTr.
+* axios updated to `0.19.0` by @SteveShaffer
+* TypeScript defitions updated by @LukoyanovE. Added `secret` and `inject` function.
+
+## 2.1.3
+
+* Fixed autoLogin plugin to inject `login` function
+* Fixed using `toString()` in DataTablewhen it is defined by @tsuemura
+
+## 2.1.2
+
+* Fixed `inject` to load objects recursively.
+* Fixed TypeScript definitions for locators by @LukoyanovE
+* **EXPERIMENTAL** [WebDriver] ReactJS locators support with webdriverio v5.8+:
+
+```js
+// locating React element by name, prop, state
+I.click({ react: 'component-name', props: {}, state: {} });
+I.seeElement({ react: 'component-name', props: {}, state: {} });
+```
+
+## 2.1.1
+
+* Do not retry `within` and `session` calls inside `retryFailedStep` plugin. Fix by @tsuemura
+
+## 2.1.0
+
+* Added global `inject()` function to require actor and page objects using dependency injection. Recommended to use in page objects, step definition files, support objects:
+
+```js
+// old way
+const I = actor();
+const myPage = require('../page/myPage');
+
+// new way
+const { I, myPage } = inject();
+```
+
+* Added global `secret` function to fill in sensitive data. By @RohanHart:
+
+```js
+I.fillField('password', secret('123456'));
+```
+
+* [wdioPlugin](https://codecept.io/plugins/#wdio) Added a plugin to **support webdriverio services** including *selenium-standalone*, *sauce*, *browserstack*, etc. **Sponsored by @GSasu**
+* [Appium] Fixed `swipe*` methods by @PeterNgTr
+* BDD Gherkin Improvements:
+ * Implemented `run-multiple` for feature files. **Sponsored by @GSasu**
+ * Added `--features` and `--tests` options to `run-multiple`. **Sponsored by @GSasu**
+ * Implemented `Before` and `After` hooks in [step definitions](https://codecept.io/bdd#before)
+* Fixed running tests by absolute path. By @batalov.
+* Enabled the adding screenshot to failed test for moch-junit-reporter by @PeterNgTr.
+* [Puppeteer] Implemented `uncheckOption` and fixed behavior of `checkOption` by @aml2610
+* [WebDriver] Fixed `seeTextEquals` on empty strings by @PeterNgTr
+* [Puppeteer] Fixed launch with `browserWSEndpoint` config by @ngadiyak.
+* [Puppeteer] Fixed switching back to main window in multi-session mode by @davertmik.
+* [autoLoginPlugin] Fixed using async functions for auto login by @nitschSB
+
+> This release was partly sponsored by @GSasu. Thanks for the support!
+Do you want to improve this project? [Learn more about sponsorin CodeceptJS
+
+
+## 2.0.8
+
+* [Puppeteer] Added `downloadFile` action by @PeterNgTr.
+
+Use it with `FileSystem` helper to test availability of a file:
+```js
+ const fileName = await I.downloadFile('a.file-link');
+ I.amInPath('output');
+ I.seeFile(fileName);
+```
+> Actions `amInPath` and `seeFile` are taken from [FileSystem](https://codecept.io/helpers/FileSystem) helper
+
+* [Puppeteer] Fixed `autoLogin` plugin with Puppeteer by @davertmik
+* [WebDriver] `seeInField` should throw error if element has no value attrubite. By @PeterNgTr
+* [WebDriver] Fixed `seeTextEquals` passes for any string if element is empty by @PeterNgTr.
+* [WebDriver] Internal refctoring to use `el.isDisplayed` to match latest webdriverio implementation. Thanks to @LukoyanovE
+* [allure plugin] Add ability enable [screenshotDiff plugin](https://github.com/allure-framework/allure2/blob/master/plugins/screen-diff-plugin/README.md) by @Vorobeyko
+* [Appium] Fixed `locator.stringify` call by @LukoyanovE
+
+## 2.0.7
+
+* [WebDriver][Protractor][Nightmare] `rightClick` method implemented (fixed) in a standard way. By @davertmik
+* [WebDriver] Updated WebDriver API calls in helper. By @PeterNgTr
+* [stepByStepReportPlugin] Added `screenshotsForAllureReport` config options to automatically attach screenshots to allure reports. By @PeterNgTr
+* [allurePlugin] Added `addLabel` method by @Vorobeyko
+* Locator Builder: fixed `withChild` and `withDescendant` to match deep nested siblings by @Vorobeyko.
+
+## 2.0.6
+
+* Introduced [Custom Locator Strategies](https://codecept.io/locators#custom-locators).
+* Added [Visual Testing Guide](https://codecept.io/visual) by @puneet0191 and @MitkoTschimev.
+* [Puppeteer] [`puppeteerCoverage`](https://codecept.io/plugins#puppeteercoverage) plugin added to collect code coverage in JS. By @dvillarama
+* Make override option in `run-multiple` to respect the generated overridden config by @kinyat
+* Fixed deep merge for `container.append()`. Introduced `lodash.merge()`. By @Vorobeyko
+* Fixed saving screenshot on Windows by
+* Fix errors on using interactive shell with Allure plugin by tsuemura
+* Fixed using dynamic injections with `Scenario().injectDependencies` by @tsemura
+* [WebDriver][Puppeteer][Nightmare][Protractor] Fixed url protocol detection for non-http urls by @LukoyanovE
+* [WebDriver] Enabled compatibility with `stepByStepReport` by @tsuemura
+* [WebDriver] Fixed `grabHTMLFrom` to return innerHTML value by @Holorium. Fixed compatibility with WebDriverIO.
+* [WebDriver] `grabHTMLFrom` to return one HTML vlaue for one element matched, array if multiple elements found by @davertmik.
+* [Nightmare] Added `grabHTMLFrom` by @davertmik
+* Fixed `bootstrapAll` and `teardownAll` launch with path as argument by @LukoyanovE
+* Fixed `bootstrapAll` and `teardownAll` calls from exported object by @LukoyanovE
+* [WebDriver] Added possibility to define conditional checks interval for `waitUntil` by @LukoyanovE
+* Fixed storing current data in data driven tests in a test object. By @Vorobeyko
+* [WebDriver] Fixed `hostname` config option overwrite when setting a cloud provider. By @LukoyanovE
+* [WebDriver] `dragSlider` method implemented by @DavertMik
+* [WebDrover] Fixed `scrollTo` to use new webdriverio API by @PeterNgTr
+* Added Japanese translation file by @tsemura
+* Added `Locator.withDescendant()` method to find an element which contains a descendant (child, grandchild) by @Vorobeyko
+* [WebDriver] Fixed configuring capabilities for Selenoid and IE by @Vorobeyko
+* [WebDriver] Restore original window size when taking full size screenshot by @tsuemura
+* Enabled `throws()`,` fails()`, `retry()`, `timeout()`, `config()` functions for data driven tests. By @jjm409
+
+## 2.0.5
+
+[Broken Release]
+
+## 2.0.4
+
+* [WebDriver][Protractor][Nightmare][Puppeteer] `grabAttributeFrom` returns an array when multiple elements matched. By @PeterNgTr
+* [autoLogin plugin] Fixed merging users config by @nealfennimore
+* [autoDelay plugin] Added WebDriver to list of supported helpers by @mattin4d
+* [Appium] Fixed using locators in `waitForElement`, `waitForVisible`, `waitForInvisible`. By @eduardofinotti
+* [allure plugin] Add tags to allure reports by @Vorobeyko
+* [allure plugin] Add skipped tests to allure reports by @Vorobeyko
+* Fixed `Logged Test name | [object Object]` when used Data().Scenario(). By @Vorobeyko
+* Fixed Data().only.Scenario() to run for all datasets. By @Vorobeyko
+* [WebDriver] `attachFile` to work with hidden elements. Fixed in #1460 by @tsuemura
+
+
+
+## 2.0.3
+
+* [**autoLogin plugin**](https://codecept.io/plugins#autologin) added. Allows to log in once and reuse browser session. When session expires - automatically logs in again. Can persist session between runs by saving cookies to file.
+* Fixed `Maximum stack trace` issue in `retryFailedStep` plugin.
+* Added `locate()` function into the interactive shell.
+* [WebDriver] Disabled smartWait for interactive shell.
+* [Appium] Updated methods to use for mobile locators
+ * `waitForElement`
+ * `waitForVisible`
+ * `waitForInvisible`
+* Helper and page object generators no longer update config automatically. Please add your page objects and helpers manually.
+
+## 2.0.2
+
+* [Puppeteer] Improved handling of connection with remote browser using Puppeteer by @martomo
+* [WebDriver] Updated to webdriverio 5.2.2 by @martomo
+* Interactive pause improvements by @davertmik
+ * Disable retryFailedStep plugin in in interactive mode
+ * Removes `Interface: parseInput` while in interactive pause
+* [ApiDataFactory] Improvements
+ * added `fetchId` config option to override id retrieval from payload
+ * added `onRequest` config option to update request in realtime
+ * added `returnId` config option to return ids of created items instead of items themvelves
+ * added `headers` config option to override default headers.
+ * added a new chapter into [DataManagement](https://codecept.io/data#api-requests-using-browser-session)
+* [REST] Added `onRequest` config option
+
+
+## 2.0.1
+
+* Fixed creating project with `codecept init`.
+* Fixed error while installing webdriverio@5.
+* Added code beautifier for generated configs.
+* [WebDriver] Updated to webdriverio 5.1.0
+
+## 2.0.0
+
+* [WebDriver] **Breaking Change.** Updated to webdriverio v5. New helper **WebDriver** helper introduced.
+
+ * **Upgrade plan**:
+
+ 1. Install latest webdriverio
+ ```
+ npm install webdriverio@5 --save
+ ```
+
+ 2. Replace `WebDriverIO` => `WebDriver` helper name in config.
+ 3. Read [webdriverio changelog](https://github.com/webdriverio/webdriverio/blob/master/CHANGELOG.md). If you were using webdriver API in your helpers, upgrade accordingly.
+ 4. We made WebDriver helper to be compatible with old API so no additional changes required.
+
+ > If you face issues using webdriverio v5 you can still use webdriverio 4.x and WebDriverIO helper. Make sure you have `webdriverio: ^4.0` installed.
+
+ * Known issues: `attachFile` doesn't work with proxy server.
+
+* [Appium] **Breaking Change.** Updated to use webdriverio v5 as well. See upgrade plan ↑
+* [REST] **Breaking Change.** Replaced `unirest` library with `axios`.
+
+ * **Upgrade plan**:
+
+ 1. Refer to [axios API](https://github.com/axios/axios).
+ 2. If you were using `unirest` requests/responses in your tests change them to axios format.
+* **Breaking Change.** Generators support in tests removed. Use `async/await` in your tests
+* **Using `codecept.conf.js` as default configuration format**
+* Fixed "enametoolong" error when saving screenshots for data driven tests by @PeterNgTr
+* Updated NodeJS to 10 in Docker image
+* [Pupeteer] Add support to use WSEndpoint. Allows to execute tests remotely. [See #1350] by @gabrielcaires (https://github.com/codeceptjs/CodeceptJS/pull/1350)
+* In interactive shell [Enter] goes to next step. Improvement by @PeterNgTr.
+* `I.say` accepts second parameter as color to print colorful comments. Improvement by @PeterNgTr.
+
+```js
+I.say('This is red', 'red'); //red is used
+I.say('This is blue', 'blue'); //blue is used
+I.say('This is by default'); //cyan is used
+```
+* Fixed allure reports for multi session testing by @PeterNgTr
+* Fixed allure reports for hooks by @PeterNgTr
+
+## 1.4.6
+
+* [Puppeteer] `dragSlider` action added by @PeterNgTr
+* [Puppeteer] Fixed opening browser in shell mode by @allenhwkim
+* [Puppeteer] Fixed making screenshot on additional sessions by @PeterNgTr. Fixes #1266
+* Added `--invert` option to `run-multiple` command by @LukoyanovE
+* Fixed steps in Allure reports by @PeterNgTr
+* Add option `output` to customize output directory in [stepByStepReport plugin](https://codecept.io/plugins/#stepbystepreport). By @fpsthirty
+* Changed type definition of PageObjects to get auto completion by @rhicu
+* Fixed steps output for async/arrow functions in CLI by @LukoyanovE. See #1329
+
+## 1.4.5
+
+* Add **require** param to main config. Allows to require Node modules before executing tests. By @LukoyanovE. For example:
+ * Use `ts-node/register` to register TypeScript parser
+ * Use `should` to register should-style assertions
+
+```js
+"require": ["ts-node/register", "should"]
+```
+
+* [WebDriverIO] Fix timeouts definition to be compatible with W3C drivers. By @LukoyanovE
+* Fixed: exception in Before block w/ Mocha causes test not to report failure. See #1292 by @PeterNgTr
+* Command `run-parallel` now accepts `--override` flag. Thanks to @ClemCB
+* Fixed Allure report with Before/BeforeSuite/After/AfterSuite steps. By @PeterNgTr
+* Added `RUN_MULTIPLE` env variable to [Docker config](https://codecept.io/docker/). Allows to run tests in parallel inside a container. Thanks to @PeterNgTr
+* [Mochawesome] Fixed showing screenshot on failure. Fix by @PeterNgTr
+* Fixed running tests filtering by tag names defined via `Scenario.tag()`
+
+## 1.4.4
+
+* [autoDelay plugin](https://codecept.io/plugins/#autoDelay) added. Adds tiny delay before and after an action so the page could react to actions performed.
+* [Puppeteer] improvements by @luismanuel001
+ * `click` no longer waits for navigation
+ * `clickLink` method added. Performs a click and waits for navigation.
+* Bootstrap scripts to be started only for `run` command and ignored on `list`, `def`, etc. Fix by @LukoyanovE
+
+
+## 1.4.3
+
+* Groups renamed to Tags for compatibility with BDD layer
+* Test and suite objects to contain tags property which can be accessed from internal API
+* Fixed adding tags for Scenario Outline in BDD
+* Added `tag()` method to ScenarioConfig and FeatureConfig:
+
+```js
+Scenario('update user profile', () => {
+ // test goes here
+}).tag('@slow');
+```
+
+* Fixed attaching Allure screenshot on exception. Fix by @DevinWatson
+* Improved type definitions for custom steps. By @Akxe
+* Fixed setting `multiple.parallel.chunks` as environment variable in config. See #1238 by @ngadiyak
+
+## 1.4.2
+
+* Fixed setting config for plugins (inclunding setting `outputDir` for allure) by @jplegoff
+
+## 1.4.1
+
+* Added `plugins` option to `run-multiple`
+* Minor output fixes
+* Added Type Definition for Helper class by @Akxe
+* Fixed extracing devault extension in generators by @Akxe
+
+## 1.4.0
+
+* [**Allure Reporter Integration**](https://codecept.io/reports/#allure). Full inegration with Allure Server. Get nicely looking UI for tests,including steps, nested steps, and screenshots. Thanks **Natarajan Krishnamurthy @krish** for sponsoring this feature.
+* [Plugins API introduced](https://codecept.io/hooks/#plugins). Create custom plugins for CodeceptJS by hooking into event dispatcher, and using promise recorder.
+* **Official [CodeceptJS plugins](https://codecept.io/plugins) added**:
+ * **`stepByStepReport` - creates nicely looking report to see test execution as a slideshow**. Use this plugin to debug tests in headless environment without recording a video.
+ * `allure` - Allure reporter added as plugin.
+ * `screenshotOnFail` - saves screenshot on fail. Replaces similar functionality from helpers.
+ * `retryFailedStep` - to rerun each failed step.
+* [Puppeteer] Fix `executeAsyncScript` unexpected token by @jonathanz
+* Added `override` option to `run-multiple` command by @svarlet
+
+## 1.3.3
+
+* Added `initGlobals()` function to API of [custom runner](https://codecept.io/hooks/#custom-runner).
+
+## 1.3.2
+
+* Interactve Shell improvements for `pause()`
+ * Added `next` command for **step-by-step debug** when using `pause()`.
+ * Use `After(pause);` in a to start interactive console after last step.
+* [Puppeteer] Updated to Puppeteer 1.6.0
+ * Added `waitForRequest` to wait for network request.
+ * Added `waitForResponse` to wait for network response.
+* Improved TypeScript definitions to support custom steps and page objects. By @xt1
+* Fixed XPath detection to accept XPath which starts with `./` by @BenoitZugmeyer
+
+## 1.3.1
+
+* BDD-Gherkin: Fixed running async steps.
+* [Puppeteer] Fixed process hanging for 30 seconds. Page loading timeout default via `getPageTimeout` set 0 seconds.
+* [Puppeteer] Improved displaying client-side console messages in debug mode.
+* [Puppeteer] Fixed closing sessions in `restart:false` mode for multi-session mode.
+* [Protractor] Fixed `grabPopupText` to not throw error popup is not opened.
+* [Protractor] Added info on using 'direct' Protractor driver to helper documentation by @xt1.
+* [WebDriverIO] Added a list of all special keys to WebDriverIO helper by @davertmik and @xt1.
+* Improved TypeScript definitions generator by @xt1
+
+## 1.3.0
+
+* **Cucumber-style BDD. Introduced [Gherkin support](https://codecept.io/bdd). Thanks to [David Vins](https://github.com/dvins) and [Omedym](https://www.omedym.com) for sponsoring this feature**.
+
+Basic feature file:
+
+```gherkin
+Feature: Business rules
+ In order to achieve my goals
+ As a persona
+ I want to be able to interact with a system
+
+ Scenario: do anything in my life
+ Given I need to open Google
+```
+
+Step definition:
+
+```js
+const I = actor();
+
+Given('I need to open Google', () => {
+ I.amOnPage('https://google.com');
+});
+```
+
+Run it with `--features --steps` flag:
+
+```
+codeceptjs run --steps --features
+```
+
+---
+
+* **Brekaing Chnage** `run` command now uses relative path + test name to run exactly one test file.
+
+Previous behavior (removed):
+```
+codeceptjs run basic_test.js
+```
+Current behavior (relative path to config + a test name)
+
+```
+codeceptjs run tests/basic_test.js
+```
+This change allows using auto-completion when running a specific test.
+
+---
+
+* Nested steps output enabled for page objects.
+ * to see high-level steps only run tests with `--steps` flag.
+ * to see PageObjects implementation run tests with `--debug`.
+* PageObjects simplified to remove `_init()` extra method. Try updated generators and see [updated guide](https://codecept.io/pageobjects/#pageobject).
+* [Puppeteer] [Multiple sessions](https://codecept.io/acceptance/#multiple-sessions) enabled. Requires Puppeteer >= 1.5
+* [Puppeteer] Stability improvement. Waits for for `load` event on page load. This strategy can be changed in config:
+ * `waitForNavigation` config option introduced. Possible options: `load`, `domcontentloaded`, `networkidle0`, `networkidle2`. See [Puppeteer API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions)
+ * `getPageTimeout` config option to set maximum navigation time in milliseconds. Default is 30 seconds.
+ * `waitForNavigation` method added. Explicitly waits for navigation to be finished.
+* [WebDriverIO][Protractor][Puppeteer][Nightmare] **Possible BC** `grabTextFrom` unified. Return a text for single matched element and an array of texts for multiple elements.
+* [Puppeteer]Fixed `resizeWindow` by @sergejkaravajnij
+* [WebDriverIO][Protractor][Puppeteer][Nightmare] `waitForFunction` added. Waits for client-side JavaScript function to return true by @GREENpoint.
+* [Puppeteer] `waitUntil` deprecated in favor of `waitForFunction`.
+* Added `filter` function to DataTable.
+* Send non-nested array of files to custom parallel execution chunking by @mikecbrant.
+* Fixed invalid output directory path for run-multiple by @mikecbrant.
+* [WebDriverIO] `waitUntil` timeout accepts time in seconds (as all other wait* functions). Fix by @truesrc.
+* [Nightmare] Fixed `grabNumberOfVisibleElements` to work similarly to `seeElement`. Thx to @stefanschenk and Jinbo Jinboson.
+* [Protractor] Fixed alert handling error with message 'no such alert' by @truesrc.
+
+
+## 1.2.1
+
+* Fixed running `I.retry()` on multiple steps.
+* Fixed parallel execution wih chunks.
+* [Puppeteer] Fixed `grabNumberOfVisibleElements` to return `0` instead of throwing error if no elements are found.
+
+## 1.2.0
+
+* [WebDriverIO][Protractor][Multiple Sessions](https://codecept.io/acceptance/#multiple-sessions). Run several browser sessions in one test. Introduced `session` command, which opens additional browser window and closes it after a test.
+
+```js
+Scenario('run in different browsers', (I) => {
+ I.amOnPage('/hello');
+ I.see('Hello!');
+ session('john', () => {
+ I.amOnPage('/bye');
+ I.dontSee('Hello');
+ I.see('Bye');
+ });
+ I.see('Hello');
+});
+```
+
+* [Parallel Execution](https://codecept.io/advanced/#parallel-execution) by @sveneisenschmidt. Run tests in parallel specifying number of chunks:
+
+```js
+"multiple": {
+ "parallel": {
+ // run in 2 processes
+ "chunks": 2,
+ // run all tests in chrome
+ "browsers": ["chrome"]
+ },
+}
+```
+
+* [Locator Builder](https://codecept.io/locators). Write complex locators with simplest API combining CSS and XPath:
+
+```js
+// select 'Edit' link inside 2nd row of a table
+locate('//table')
+ .find('tr')
+ .at(2)
+ .find('a')
+ .withText('Edit');
+```
+
+* [Dynamic configuration](https://codecept.io/advanced/#dynamic-configuration) to update helpers config per test or per suite.
+* Added `event.test.finished` which fires synchronously for both failed and passed tests.
+* [WebDriverIO][Protractor][Nightmare][Puppeteer] Full page screenshots on failure disabled by default. See [issue#1600. You can enabled them with `fullPageScreenshots: true`, however they may work unstable in Selenium.
+* `within` blocks can return values. See [updated documentation](https://codecept.io/basics/#within).
+* Removed doublt call to `_init` in helpers. Fixes issue #1036
+* Added scenario and feature configuration via fluent API:
+
+```js
+Feature('checkout')
+ .timeout(3000)
+ .retry(2);
+
+Scenario('user can order in firefox', (I) => {
+ // see dynamic configuration
+}).config({ browser: 'firefox' })
+ .timeout(20000);
+
+Scenario('this test should throw error', (I) => {
+ // I.amOnPage
+}).throws(new Error);
+```
+
+## 1.1.8
+
+* Fixed generating TypeScript definitions with `codeceptjs def`.
+* Added Chinese translation ("zh-CN" and "zh-TW") by @TechQuery.
+* Fixed running tests from a different folder specified by `-c` option.
+* [Puppeteer] Added support for hash handling in URL by @gavoja.
+* [Puppeteer] Fixed setting viewport size by @gavoja. See [Puppeteer issue](https://github.com/GoogleChrome/puppeteer/issues/1183)
+
+
+## 1.1.7
+
+* Docker Image updateed. [See updated reference](https://codecept.io/docker/):
+ * codeceptjs package is mounted as `/codecept` insde container
+ * tests directory is expected to be mounted as `/tests`
+ * `codeceptjs` global runner added (symlink to `/codecept/bin/codecept.js`)
+* [Protractor] Functions added by @reubenmiller:
+ * `_locateCheckable (only available from other helpers)`
+ * `_locateClickable (only available from other helpers)`
+ * `_locateFields (only available from other helpers)`
+ * `acceptPopup`
+ * `cancelPopup`
+ * `dragAndDrop`
+ * `grabBrowserLogs`
+ * `grabCssPropertyFrom`
+ * `grabHTMLFrom`
+ * `grabNumberOfVisibleElements`
+ * `grabPageScrollPosition (new)`
+ * `rightClick`
+ * `scrollPageToBottom`
+ * `scrollPageToTop`
+ * `scrollTo`
+ * `seeAttributesOnElements`
+ * `seeCssPropertiesOnElements`
+ * `seeInPopup`
+ * `seeNumberOfVisibleElements`
+ * `switchTo`
+ * `waitForEnabled`
+ * `waitForValue`
+ * `waitInUrl`
+ * `waitNumberOfVisibleElements`
+ * `waitToHide`
+ * `waitUntil`
+ * `waitUrlEquals`
+* [Nightmare] added:
+ * `grabPageScrollPosition` (new)
+ * `seeNumberOfVisibleElements`
+ * `waitToHide`
+* [Puppeteer] added:
+ * `grabPageScrollPosition` (new)
+* [WebDriverIO] added"
+ * `grabPageScrollPosition` (new)
+* [Puppeteer] Fixed running wait* functions without setting `sec` parameter.
+* [Puppeteer][Protractor] Fixed bug with I.click when using an object selector with the xpath property. By @reubenmiller
+* [WebDriverIO][Protractor][Nightmare][Puppeteer] Fixed I.switchTo(0) and I.scrollTo(100, 100) api inconsistencies between helpers.
+* [Protractor] Fixing bug when `seeAttributesOnElements` and `seeCssPropertiesOnElement` were incorrectly passing when the attributes/properties did not match by @reubenmiller
+* [WebDriverIO] Use inbuilt dragAndDrop function (still doesn't work in Firefox). By @reubenmiller
+* Support for Nightmare 3.0
+* Enable glob patterns in `config.test` / `Codecept.loadTests` by @sveneisenschmidt
+* Enable overriding of `config.tests` for `run-multiple` by @sveneisenschmidt
+
+
+## 1.1.6
+
+* Added support for `async I =>` functions syntax in Scenario by @APshenkin
+* [WebDriverIO][Protractor][Puppeteer][Nightmare] `waitForInvisible` waits for element to hide or to be removed from page. By @reubenmiller
+* [Protractor][Puppeteer][Nightmare] Added `grabCurrentUrl` function. By @reubenmiller
+* [WebDriverIO] `grabBrowserUrl` deprecated in favor of `grabCurrentUrl` to unify the API.
+* [Nightmare] Improved element visibility detection by @reubenmiller
+* [Puppeteer] Fixing function calls when clearing the cookies and localstorage. By @reubenmiller
+* [Puppeteer] Added `waitForEnabled`, `waitForValue` and `waitNumberOfVisibleElements` methods by @reubenmiller
+* [WebDriverIO] Fixed `grabNumberOfVisibleElements` to return 0 when no visible elements are on page. By @michaltrunek
+* Helpers API improvements (by @reubenmiller)
+ * `_passed` hook runs after a test passed successfully
+ * `_failed` hook runs on a failed test
+* Hooks API. New events added by @reubenmiller:
+ * `event.all.before` - executed before all tests
+ * `event.all.after` - executed after all tests
+ * `event.multiple.before` - executed before all processes in run-multiple
+ * `event.multiple.after` - executed after all processes in run-multiple
+* Multiple execution
+* Allow `AfterSuite` and `After` test hooks to be defined after the first Scenario. By @reubenmiller
+* [Nightmare] Prevent `I.amOnpage` navigation if the browser is already at the given url
+* Multiple-Run: Added new `bootstrapAll` and `teardownAll` hooks to be executed before and after all processes
+* `codeceptjs def` command accepts `--config` option. By @reubenmiller
+
+## 1.1.5
+
+* [Puppeteer] Rerun steps failed due to "Cannot find context with specified id" Error.
+* Added syntax to retry a single step:
+
+```js
+// retry action once on failure
+I.retry().see('Hello');
+
+// retry action 3 times on failure
+I.retry(3).see('Hello');
+
+// 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');
+```
+
+* `Scenario().injectDependencies` added to dynamically add objects into DI container by @Apshenkin. See [Dependency Injection section in PageObjects](https://codecept.io/pageobjects/#dependency-injection).
+* Fixed using async/await functions inside `within`
+* [WebDriverIO][Protractor][Puppeteer][Nightmare] **`waitUntilExists` deprecated** in favor of `waitForElement`
+* [WebDriverIO][Protractor] **`waitForStalenessOf` deprecated** in favor of `waitForDetached`
+* [WebDriverIO][Protractor][Puppeteer][Nightmare] `waitForDetached` added
+* [Nightmare] Added `I.seeNumberOfElements()` by @pmoncadaisla
+* [Nightmare] Load blank page when starting nightmare so that the .evaluate function will work if _failed/saveScreenshot is triggered by @reubenmiller
+* Fixed using plain arrays for data driven tests by @reubenmiller
+* [Puppeteer] Use default tab instead of opening a new tab when starting the browser by @reubenmiller
+* [Puppeteer] Added `grabNumberOfTabs` function by @reubenmiller
+* [Puppeteer] Add ability to set user-agent by @abidhahmed
+* [Puppeteer] Add keepCookies and keepBrowserState @abidhahmed
+* [Puppeteer] Clear value attribute instead of innerhtml for TEXTAREA by @reubenmiller
+* [REST] fixed sending string payload by @michaltrunek
+* Fixed unhandled rejection in async/await tests by @APshenkin
+
+
+## 1.1.4
+
+* Removed `yarn` call in package.json
+* Fixed `console.log` in Puppeteer by @othree
+* [Appium] `runOnAndroid` and `runOnIOS` can receive a function to check capabilities dynamically:
+
+```js
+I.runOnAndroid(caps => caps.platformVersion >= 7, () => {
+ // run code only on Android 7+
+});
+```
+
+## 1.1.3
+
+* [Puppeteer] +25 Functions added by @reubenmiller
+ * `_locateCheckable`
+ * `_locateClickable`
+ * `_locateFields`
+ * `closeOtherTabs`
+ * `dragAndDrop`
+ * `grabBrowserLogs`
+ * `grabCssPropertyFrom`
+ * `grabHTMLFrom`
+ * `grabNumberOfVisibleElements`
+ * `grabSource`
+ * `rightClick`
+ * `scrollPageToBottom`
+ * `scrollPageToTop`
+ * `scrollTo`
+ * `seeAttributesOnElements`
+ * `seeCssPropertiesOnElements`
+ * `seeInField`
+ * `seeNumberOfElements`
+ * `seeNumberOfVisibleElements`
+ * `seeTextEquals`
+ * `seeTitleEquals`
+ * `switchTo`
+ * `waitForInvisible`
+ * `waitInUrl`
+ * `waitUrlEquals`
+* [Protractor] +8 functions added by @reubenmiller
+ * `closeCurrentTab`
+ * `grabSource`
+ * `openNewTab`
+ * `seeNumberOfElements`
+ * `seeTextEquals`
+ * `seeTitleEquals`
+ * `switchToNextTab`
+ * `switchToPreviousTab`
+* [Nightmare] `waitForInvisible` added by @reubenmiller
+* [Puppeteer] Printing console.log information in debug mode.
+* [Nightmare] Integrated with `nightmare-har-plugin` by mingfang. Added `enableHAR` option. Added HAR functions:
+ * `grabHAR`
+ * `saveHAR`
+ * `resetHAR`
+* [WebDriverIO] Fixed execution stability for parallel requests with Chromedriver
+* [WebDriverIO] Fixed resizeWindow when resizing to 'maximize' by @reubenmiller
+* [WebDriverIO] Fixing resizing window to full screen when taking a screenshot by @reubenmiller
+
+## 1.1.2
+
+* [Puppeteer] Upgraded to Puppeteer 1.0
+* Added `grep` option to config to set default matching pattern for tests.
+* [Puppeteer] Added `acceptPopup`, `cancelPopup`, `seeInPopup` and `grabPopupText` functions by @reubenmiller
+* [Puppeteer] `within` iframe and nested iframe support added by @reubenmiller
+* [REST] Added support for JSON objects since payload (as a JSON) was automatically converted into "URL query" type of parameter by @Kalostrinho
+* [REST] Added `resetRequestHeaders` method by @Kalostrinho
+* [REST] Added `followRedirect` option and `amFollowingRequestRedirects`/`amNotFollowingRequestRedirects` methods by @Kalostrinho
+* [WebDriverIO] `uncheckOption` implemented by @brunobg
+* [WebDriverIO] Added `grabBrowserUrl` by @Kalostrinho
+* Add ability to require helpers from node_modules by @APshenkin
+* Added `--profile` option to `run-multiple` command by @jamie-beck
+* Custom output name for multiple browser run by @tfiwm
+* Fixed passing data to scenarios by @KennyRules
+
+## 1.1.1
+
+* [WebDriverIO] fixed `waitForInvisible` by @Kporal
+
+## 1.1.0
+
+Major update to CodeceptJS. **NodeJS v 8.9.1** is now minimal Node version required.
+This brings native async-await support to CodeceptJS. It is recommended to start using await for tests instead of generators:
+
+```js
+async () => {
+ I.amOnPage('/page');
+ const url = await I.grabTextFrom('.nextPage');
+ I.amOnPage(url);
+}
+```
+
+Thanks to [@Apshenkin](https://github.com/apshenkin) for implementation. Also, most helpers were refactored to use async-await. This made our code simpler. We hope that this encourages more users to send pull requests!
+
+We also introduced strict ESLint policies for our codebase. Thanks to [@Galkin](https://github.com/galkin) for that.
+
+* **[Puppeteer] Helper introduced**. [Learn how to run tests headlessly with Google Chrome's Puppeteer](http://codecept.io/puppeteer/).
+* [SeleniumWebdriver] Helper is deprecated, it is recommended to use Protractor with config option `angular: false` instead.
+* [WebDriverIO] nested iframe support in the within block by @reubenmiller. Example:
+
+```js
+within({frame: ['#wrapperId', '[name=content]']}, () => {
+ I.click('Sign in!');
+ I.see('Email Address');
+});
+I.see('Nested Iframe test');
+I.dontSee('Email Address');
+});
+```
+* [WebDriverIO] Support for `~` locator to find elements by `aria-label`. This behavior is similar as it is in Appium and helps testing cross-platform React apps. Example:
+
+```html
+
+ CodeceptJS is awesome
+
+```
+↑ This element can be located with `~foobar` in WebDriverIO and Appium helpers. Thanks to @flyskywhy
+
+* Allow providing arbitrary objects in config includes by @rlewan
+* [REST] Prevent from mutating default headers by @alexashley. See #789
+* [REST] Fixed sending empty helpers with `haveRequestHeaders` in `sendPostRequest`. By @petrisorionel
+* Fixed displaying undefined args in output by @APshenkin
+* Fixed NaN instead of seconds in output by @APshenkin
+* Add browser name to report file for `multiple-run` by @trollr
+* Mocha updated to 4.x
+
+
+
+## 1.0.3
+
+* [WebDriverIO][Protractor][Nightmare] method `waitUntilExists` implemented by @sabau
+* Absolute path can be set for `output` dir by @APshenkin. Fix #571* Data table rows can be ignored by using `xadd`. By @APhenkin
+* Added `Data(table).only.Scenario` to give ability to launch only Data tests. By @APhenkin
+* Implemented `ElementNotFound` error by @BorisOsipov.
+* Added TypeScript compiler / configs to check the JavaScript by @KennyRules
+* [Nightmare] fix executeScript return value by @jploskonka
+* [Nightmare] fixed: err.indexOf not a function when waitForText times out in nightmare by @joeypedicini92
+* Fixed: Retries not working when using .only. By @APhenkin
+
+
+## 1.0.2
+
+* Introduced generators support in scenario hooks for `BeforeSuite`/`Before`/`AfterSuite`/`After`
+* [ApiDataFactory] Fixed loading helper; `requireg` package included.
+* Fix #485`run-multiple`: the first browser-resolution combination was be used in all configurations
+* Fixed unique test names:
+ * Fixed #447 tests failed silently if they have the same name as other tests.
+ * Use uuid in screenshot names when `uniqueScreenshotNames: true`
+* [Protractor] Fixed testing non-angular application. `amOutsideAngularApp` is executed before each step. Fixes #458* Added output for steps in hooks when they fail
+
+## 1.0.1
+
+* Reporters improvements:
+ * Allows to execute [multiple reporters](http://codecept.io/advanced/#Multi-Reports)
+ * Added [Mochawesome](http://codecept.io/helpers/Mochawesome/) helper
+ * `addMochawesomeContext` method to add custom data to mochawesome reports
+ * Fixed Mochawesome context for failed screenshots.
+* [WebDriverIO] improved click on context to match clickable element with a text inside. Fixes #647* [Nightmare] Added `refresh` function by @awhanks
+* fixed `Unhandled promise rejection (rejection id: 1): Error: Unknown wait type: pageLoad`
+* support for tests with retries in html report
+* be sure that change window size and timeouts completes before test
+* [Nightmare] Fixed `[Wrapped Error] "codeceptjs is not defined"`; Reinjectiing client scripts to a webpage on changes.
+* [Nightmare] Added more detailed error messages for `Wait*` methods
+* [Nightmare] Fixed adding screenshots to Mochawesome
+* [Nightmare] Fix unique screenshots names in Nightmare
+* Fixed CodeceptJS work with hooks in helpers to finish codeceptJS correctly if errors appears in helpers hooks
+* Create a new session for next test If selenium grid error received
+* Create screenshots for failed hooks from a Feature file
+* Fixed `retries` option
+
+## 1.0
+
+CodeceptJS hits first stable release. CodeceptJS provides a unified API for [web testing for Webdriverio](http://codecept.io/acceptance/), [Protractor](http://codecept.io/angular/), and [NightmareJS](http://codecept.io/nightmare/). Since 1.0 you can also **test mobile applications** in the similar manner with Appium.
+
+Sample test:
+
+```js
+I.seeAppIsInstalled("io.super.app");
+I.click('~startUserRegistrationCD');
+I.fillField('~email of the customer', 'Nothing special'));
+I.see('davert@codecept.io', '~email of the customer'));
+I.clearField('~email of the customer'));
+I.dontSee('Nothing special', '~email of the customer'));
+```
+
+* Read [the Mobile Testing guide](http://codecept.io/mobile).
+* Discover [Appium Helper](http://codecept.io/helpers/Appium/)
+
+---
+
+We also introduced two new **helpers for data management**.
+Using them you can easily prepare and cleanup data for your tests using public REST API.
+
+Sample test
+
+```js
+// create a user using data factories and REST API
+I.have('user', { name: 'davert', password: '123456' });
+// use it to login
+I.amOnPage('/login');
+I.fillField('login', 'davert');
+I.fillField('password', '123456');
+I.click('Login');
+I.see('Hello, davert');
+// user will be removed after the test
+```
+
+* Read [Data Management guide](http://codecept.io/data)
+* [REST Helper](http://codecept.io/helpers/REST)
+* [ApiDataFactory](http://codecept.io/helpers/ApiDataFactory/)
+
+---
+
+Next notable feature is **[SmartWait](http://codecept.io/acceptance/#smartwait)** for WebDriverIO, Protractor, SeleniumWebdriver. When `smartwait` option is set, script will wait for extra milliseconds to locate an element before failing. This feature uses implicit waits of Selenium but turns them on only in applicable pieces. For instance, implicit waits are enabled for `seeElement` but disabled for `dontSeeElement`
+
+* Read more about [SmartWait](http://codecept.io/acceptance/#smartwait)
+
+##### Changelog
+
+* Minimal NodeJS version is 6.11.1 LTS
+* Use `within` command with generators.
+* [Data Driven Tests](http://codecept.io/advanced/#data-driven-tests) introduced.
+* Print execution time per step in `--debug` mode. #591 by @APshenkin
+* [WebDriverIO][Protractor][Nightmare] Added `disableScreenshots` option to disable screenshots on fail by @Apshenkin
+* [WebDriverIO][Protractor][Nightmare] Added `uniqueScreenshotNames` option to generate unique names for screenshots on failure by @Apshenkin
+* [WebDriverIO][Nightmare] Fixed click on context; `click('text', '#el')` will throw exception if text is not found inside `#el`.
+* [WebDriverIO][Protractor][SeleniumWebdriver] [SmartWait introduced](http://codecept.io/acceptance/#smartwait).
+* [WebDriverIO][Protractor][Nightmare]Fixed `saveScreenshot` for PhantomJS, `fullPageScreenshots` option introduced by @HughZurname #549
+* [Appium] helper introduced by @APshenkin
+* [REST] helper introduced by @atrevino in #504
+* [WebDriverIO][SeleniumWebdriver] Fixed "windowSize": "maximize" for Chrome 59+ version #560 by @APshenkin
+* [Nightmare] Fixed restarting by @APshenkin #581
+* [WebDriverIO] Methods added by @APshenkin:
+ * [grabCssPropertyFrom](http://codecept.io/helpers/WebDriverIO/#grabcsspropertyfrom)
+ * [seeTitleEquals](http://codecept.io/helpers/WebDriverIO/#seetitleequals)
+ * [seeTextEquals](http://codecept.io/helpers/WebDriverIO/#seetextequals)
+ * [seeCssPropertiesOnElements](http://codecept.io/helpers/WebDriverIO/#seecsspropertiesonelements)
+ * [seeAttributesOnElements](http://codecept.io/helpers/WebDriverIO/#seeattributesonelements)
+ * [grabNumberOfVisibleElements](http://codecept.io/helpers/WebDriverIO/#grabnumberofvisibleelements)
+ * [waitInUrl](http://codecept.io/helpers/WebDriverIO/#waitinurl)
+ * [waitUrlEquals](http://codecept.io/helpers/WebDriverIO/#waiturlequals)
+ * [waitForValue](http://codecept.io/helpers/WebDriverIO/#waitforvalue)
+ * [waitNumberOfVisibleElements](http://codecept.io/helpers/WebDriverIO/#waitnumberofvisibleelements)
+ * [switchToNextTab](http://codecept.io/helpers/WebDriverIO/#switchtonexttab)
+ * [switchToPreviousTab](http://codecept.io/helpers/WebDriverIO/#switchtoprevioustab)
+ * [closeCurrentTab](http://codecept.io/helpers/WebDriverIO/#closecurrenttab)
+ * [openNewTab](http://codecept.io/helpers/WebDriverIO/#opennewtab)
+ * [refreshPage](http://codecept.io/helpers/WebDriverIO/#refreshpage)
+ * [scrollPageToBottom](http://codecept.io/helpers/WebDriverIO/#scrollpagetobottom)
+ * [scrollPageToTop](http://codecept.io/helpers/WebDriverIO/#scrollpagetotop)
+ * [grabBrowserLogs](http://codecept.io/helpers/WebDriverIO/#grabbrowserlogs)
+* Use mkdirp to create output directory. #592 by @vkramskikh
+* [WebDriverIO] Fixed `seeNumberOfVisibleElements` by @BorisOsipov #574
+* Lots of fixes for promise chain by @APshenkin #568
+ * Fix #543- After block not properly executed if Scenario fails
+ * Expected behavior in promise chains: `_beforeSuite` hooks from helpers -> `BeforeSuite` from test -> `_before` hooks from helpers -> `Before` from test - > Test steps -> `_failed` hooks from helpers (if test failed) -> `After` from test -> `_after` hooks from helpers -> `AfterSuite` from test -> `_afterSuite` hook from helpers.
+ * if during test we got errors from any hook (in test or in helper) - stop complete this suite and go to another
+ * if during test we got error from Selenium server - stop complete this suite and go to another
+ * [WebDriverIO][Protractor] if `restart` option is false - close all tabs expect one in `_after`.
+ * Complete `_after`, `_afterSuite` hooks even After/AfterSuite from test was failed
+ * Don't close browser between suites, when `restart` option is false. We should start browser only one time and close it only after all tests.
+ * Close tabs and clear local storage, if `keepCookies` flag is enabled
+* Fix TypeError when using babel-node or ts-node on node.js 7+ #586 by @vkramskikh
+* [Nightmare] fixed usage of `_locate`
+
+Special thanks to **Andrey Pshenkin** for his work on this release and the major improvements.
+
+## 0.6.3
+
+* Errors are printed in non-verbose mode. Shows "Selenium not started" and other important errors.
+* Allowed to set custom test options:
+
+```js
+Scenario('My scenario', { build_id: 123, type: 'slow' }, function (I)
+```
+those options can be accessed as `opts` property inside a `test` object. Can be used in custom listeners.
+
+* Added `docs` directory to a package.
+* [WebDriverIO][Protractor][SeleniumWebdriver] Bugfix: cleaning session when `restart: false` by @tfiwm #519
+* [WebDriverIO][Protractor][Nightmare] Added second parameter to `saveScreenshot` to allow a full page screenshot. By @HughZurname
+* Added suite object to `suite.before` and `suite.after` events by @implico. #496
+
+## 0.6.2
+
+* Added `config` object to [public API](http://codecept.io/hooks/#api)
+* Extended `index.js` to include `actor` and `helpers`, so they could be required:
+
+```js
+const actor = require('codeceptjs').actor;
+```
+
+* Added [example for creating custom runner](http://codecept.io/hooks/#custom-runner) with public API.
+* run command to create `output` directory if it doesn't exist
+* [Protractor] fixed loading globally installed Protractor
+* run-multiple command improvements:
+ * create output directories for each process
+ * print process ids in output
+
+## 0.6.1
+
+* Fixed loading hooks
+
+## 0.6.0
+
+Major release with extension API and parallel execution.
+
+* **Breaking** Removed path argument from `run`. To specify path other than current directory use `--config` or `-c` option:
+
+Instead of: `codeceptjs run tests` use:
+
+```
+# load config and run from tests directory
+codeceptjs run -c tests/
+
+# or load codecept.json from tests directory
+codeceptjs run -c tests/codecept.json
+
+# run users_test.js inside tests directory
+codeceptjs run users_test.js -c tests
+```
+
+* **Command `multiple-run` added**, to execute tests in several browsers in parallel by @APshenkin and @davertmik. [See documentation](http://codecept.io/advanced/#multiple-execution).
+* **Hooks API added to extend CodeceptJS** with custom listeners and plugins. [See documentation](http://codecept.io/hooks/#hooks_1).
+* [Nightmare][WebDriverIO] `within` can work with iframes by @imvetri. [See documentation](http://codecept.io/acceptance/#iframes).
+* [WebDriverIO][SeleniumWebdriver][Protractor] Default browser changed to `chrome`
+* [Nightmare] Fixed globally locating `nightmare-upload`.
+* [WebDriverIO] added `seeNumberOfVisibleElements` method by @elarouche.
+* Exit with non-zero code if init throws an error by @rincedd
+* New guides published:
+ * [Installation](http://codecept.io/installation/)
+ * [Hooks](http://codecept.io/hooks/)
+ * [Advanced Usage](http://codecept.io/advanced/)
+* Meta packages published:
+ * [codecept-webdriverio](https://www.npmjs.com/package/codecept-webdriverio)
+ * [codecept-protractor](https://www.npmjs.com/package/codecept-protractor)
+ * [codecept-nightmare](https://www.npmjs.com/package/codecept-nightmare)
+
+
+## 0.5.1
+
+* [Polish translation](http://codecept.io/translation/#polish) added by @limes.
+* Update process exit code so that mocha saves reports before exit by @romanovma.
+* [Nightmare] fixed `getAttributeFrom` for custom attributes by @robrkerr
+* [Nightmare] Fixed *UnhandledPromiseRejectionWarning error* when selecting the dropdown using `selectOption` by @robrkerr. [Se PR.
+* [Protractor] fixed `pressKey` method by @romanovma
+
## 0.5.0
* Protractor ^5.0.0 support (while keeping ^4.0.9 compatibility)
-* Fix 'fullTitle() is not a function' in exit.js by @hubidu. See [#388](https://github.com/Codeception/CodeceptJS/pull/388).
-* [Nightmare] Fix for `waitTimeout` by @HughZurname. See [#391](https://github.com/Codeception/CodeceptJS/pull/391). Resolves [#236](https://github.com/Codeception/CodeceptJS/issues/236)
-* Dockerized CodeceptJS setup by @artiomnist. [See reference](https://github.com/Codeception/CodeceptJS/blob/master/docker/README.md)
+* Fix 'fullTitle() is not a function' in exit.js by @hubidu. See #388.
+* [Nightmare] Fix for `waitTimeout` by @HughZurname. See #391. Resolves #236* Dockerized CodeceptJS setup by @artiomnist. [See reference](https://github.com/codeceptjs/CodeceptJS/blob/master/docker/README.md)
## 0.4.16
@@ -85,7 +1443,7 @@ Scenario('Not that complex', {timeout: 1000}, (I) => {
});
```
-* [WebDriverIO] Added `uniqueScreenshotNames` option to set unique screenshot names for failed tests. By @APshenkin. See [#299](https://github.com/Codeception/CodeceptJS/pull/299)
+* [WebDriverIO] Added `uniqueScreenshotNames` option to set unique screenshot names for failed tests. By @APshenkin. See #299
* [WebDriverIO] `clearField` method improved to accept name/label locators and throw errors.
* [Nightmare][SeleniumWebdriver][Protractor] `clearField` method added.
* [Nightmare] Fixed `waitForElement`, and `waitForVisible` methods.
@@ -102,7 +1460,7 @@ codeceptjs run -o '{ "bootstrap": "bootstrap.js"}'
codeceptjs run -o '{ "helpers": {"WebDriverIO": {"browser": "chrome"}}}'
```
-* Added [regression tests](https://github.com/Codeception/CodeceptJS/tree/master/test/runner) for codeceptjs tests runner.
+* Added [regression tests](https://github.com/codeceptjs/CodeceptJS/tree/master/test/runner) for codeceptjs tests runner.
## 0.4.11
@@ -136,12 +1494,12 @@ module.exports = function(done) {
## 0.4.8
* [Protractor][SeleniumWebdriver][Nightmare] added `moveCursorTo` method.
-* [Protractor][SeleniumWebdriver][WebDriverIO] Added `manualStart` option to start browser manually in the beginning of test. By @cnworks. [PR #250](https://github.com/Codeception/CodeceptJS/pull/255)
+* [Protractor][SeleniumWebdriver][WebDriverIO] Added `manualStart` option to start browser manually in the beginning of test. By @cnworks. [PR#250
* Fixed `codeceptjs init` to work with nested directories and file masks.
* Fixed `codeceptjs gt` to generate test with proper file name suffix. By @Zougi.
* [Nightmare] Fixed: Error is thrown when clicking on element which can't be locate. By @davetmik
* [WebDriverIO] Fixed `attachFile` for file upload. By @giuband and @davetmik
-* [WebDriverIO] Add support for timeouts in config and with `defineTimeouts` method. By @easternbloc [#258](https://github.com/Codeception/CodeceptJS/pull/258) and [#267](https://github.com/Codeception/CodeceptJS/pull/267) by @davetmik
+* [WebDriverIO] Add support for timeouts in config and with `defineTimeouts` method. By @easternbloc #258 and #267 by @davetmik
* Fixed hanging of CodeceptJS when error is thrown by event dispatcher. Fix by @Zougi and @davetmik
@@ -185,7 +1543,7 @@ exports.config = {
## 0.4.2
-* Added ability to localize tests with translation [#189](https://github.com/Codeception/CodeceptJS/pull/189). Thanks to @abner
+* Added ability to localize tests with translation #189. Thanks to @abner
* [Translation] ru-RU translation added.
* [Translation] pt-BR translation added.
* [Protractor] Protractor 4.0.4 compatibility.
@@ -315,4 +1673,4 @@ Whenever you need to create `I` object (in page objects, custom steps, but not i
* [WebDriverIO] proxy configuration added by @petehouston
* [WebDriverIO] fixed `waitForText` method by @roadhump. Fixes #11
* Fixed creating output dir when it already exists on init by @alfirin
-* Fixed loading of custom helpers
\ No newline at end of file
+* Fixed loading of custom helpers
diff --git a/Dockerfile b/Dockerfile
index 4f2d777fa..05dee4522 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,29 +1,66 @@
-FROM node:6.9.5
-# LTS
+ARG NODE_VERSION=12.10.0
+FROM node:${NODE_VERSION}
- # Set grep as an ENV variable
-ENV GREP=" "
+# Add our user and group first to make sure their IDs get assigned consistently,
+# regardless of whatever dependencies get added.
+RUN groupadd --system nightmare && useradd --system --create-home --gid nightmare nightmare
- # Set HOST ENV variable for Selenium Server
-ENV HOST=selenium
+# Installing the pre-required packages and libraries for electron & Nightmare
+RUN apt-get update && \
+ apt-get install -y libgtk2.0-0 libgconf-2-4 \
+ libasound2 libxtst6 libxss1 libnss3 xvfb
- # Add our user and group first to make sure their IDs get assigned consistently,
- # regardless of whatever dependencies get added.
-RUN groupadd --system nightmare && useradd --system --create-home --gid nightmare nightmare
+# Install latest chrome dev package.
+# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer
+# installs, work.
+RUN apt-get update && apt-get install -y wget --no-install-recommends \
+ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
+ && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
+ && apt-get update \
+ && apt-get install -y google-chrome-unstable \
+ --no-install-recommends \
+ && apt-get install -y libgbm1 \
+ && rm -rf /var/lib/apt/lists/* \
+ && apt-get purge --auto-remove -y curl \
+ && rm -rf /src/*.deb
- # Installing the pre-required packages and libraries for electron & Nightmare
-RUN apt-get update && \
- apt-get install -y libgtk2.0-0 libgconf-2-4 \
- libasound2 libxtst6 libxss1 libnss3 xvfb
+# Uncomment to skip the chromium download when installing puppeteer. If you do,
+# you'll need to launch puppeteer with:
+# browser.launch({executablePath: 'google-chrome-unstable'})
+# ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
-ADD . /
- # Install latest version of Nightmare
-RUN npm install
+# Add pptr user.
+RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
+ && mkdir -p /home/pptruser/Downloads \
+ && chown -R pptruser:pptruser /home/pptruser \
+ && chown -R pptruser:pptruser /home/pptruser
- # Set the entrypoint for Nightmare
-ENTRYPOINT ["/docker/entrypoint"]
- # Run tests
-CMD ["bash", "/docker/run.sh"]
+#RUN mkdir /home/codecept
+COPY . /codecept
+
+RUN chown -R pptruser:pptruser /codecept
+RUN runuser -l pptruser -c 'npm install --loglevel=warn --prefix /codecept'
+
+RUN ln -s /codecept/bin/codecept.js /usr/local/bin/codeceptjs
+RUN mkdir /tests
+WORKDIR /tests
+
+# Allow to pass argument to codecept run via env variable
+ENV CODECEPT_ARGS=""
+ENV RUN_MULTIPLE=false
+ENV NO_OF_WORKERS=""
+
+# Set HOST ENV variable for Selenium Server
+ENV HOST=selenium
+
+# Run user as non privileged.
+# USER pptruser
+
+# Set the entrypoint for Nightmare
+ENTRYPOINT ["/codecept/docker/entrypoint"]
+
+# Run tests
+CMD ["bash", "/codecept/docker/run.sh"]
diff --git a/README.md b/README.md
index 6634feba1..e858a93b5 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,14 @@
-# CodeceptJS [![NPM version][npm-image]][npm-url] [](https://travis-ci.org/Codeception/CodeceptJS) [](https://gitter.im/Codeception/CodeceptJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[
](https://join.slack.com/t/codeceptjs/shared_invite/enQtMzA5OTM4NDM2MzA4LWE4MThhN2NmYTgxNTU5MTc4YzAyYWMwY2JkMmZlYWI5MWQ2MDM5MmRmYzZmYmNiNmY5NTAzM2EwMGIwOTNhOGQ) [
](https://codecept.discourse.group) [![NPM version][npm-image]][npm-url] [](https://travis-ci.org/Codeception/CodeceptJS) [](https://www.codacy.com/app/DavertMik/CodeceptJS?utm_source=github.com&utm_medium=referral&utm_content=Codeception/CodeceptJS&utm_campaign=badger) [](https://houndci.com)
-Reference: [Helpers API](https://github.com/Codeception/CodeceptJS/blob/master/docs) | [Demo](https://github.com/Codeception/codeceptjs-demo)
+# CodeceptJS
-## Modern Era Acceptance Testing Framework for NodeJS
+Reference: [Helpers API](https://github.com/codeceptjs/CodeceptJS/blob/master/docs) | [Demo](https://github.com/codeceptjs/codeceptjs-demo)
+
+## Supercharged E2E Testing
CodeceptJS is a new testing framework for end-to-end testing with WebDriver (or others).
-It abstracts browser interaction to simple steps which is written from a user perspective.
-A simple test that verifies that "Welcome" text is present on a main page of a site will look like:
+It abstracts browser interaction to simple steps that are written from a user perspective.
+A simple test that verifies the "Welcome" text is present on a main page of a site will look like:
```js
Feature('CodeceptJS demo');
@@ -14,22 +16,24 @@ Feature('CodeceptJS demo');
Scenario('check Welcome page on site', (I) => {
I.amOnPage('/');
I.see('Welcome');
-}
+});
```
-Codeception tests are:
+CodeceptJS tests are:
-* **Synchronous**. You don't need to care about callbacks, or promises, test scenarios are linear, your test should be too.
+* **Synchronous**. You don't need to care about callbacks or promises or test scenarios which are linear. But, your tests should be linear.
* Written from **user's perspective**. Every action is a method of `I`. That makes test easy to read, write and maintain even for non-tech persons.
* Backend **API agnostic**. We don't know which WebDriver implementation is running this test. We can easily switch from WebDriverIO to Protractor or PhantomJS.
-Codeception uses **Helper** modules to provide actions to `I` object. Currently CodeceptJS has these helpers:
+CodeceptJS uses **Helper** modules to provide actions to `I` object. Currently CodeceptJS has these helpers:
-* [**WebDriverIO**](https://github.com/Codeception/CodeceptJS/blob/master/docs/helpers/WebDriverIO.md) - wrapper on top of Selenium bindings library [WebDriverIO](http://webdriver.io/)
-* [**Protractor**](https://github.com/Codeception/CodeceptJS/blob/master/docs/helpers/Protractor.md) - helper enpowered by [Protractor](http://protractortest.org/) framework for AngularJS testing
-* [**Nightmare**](https://github.com/Codeception/CodeceptJS/blob/master/docs/helpers/Nightmare.md) - helper which for testing web applications indi Electron using NightmareJS.
-* [**SeleniumWebdriver**](https://github.com/Codeception/CodeceptJS/blob/master/docs/helpers/SeleniumWebdriver.md) - helper which for selenium testing using official Selenium Webdriver JS bindings.
-* [**FileSystem**](https://github.com/Codeception/CodeceptJS/blob/master/docs/helpers/FileSystem.md) - simple helper for testing filesystem.
+* [**Puppeteer**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Puppeteer.md) - uses Google Chrome's Puppeteer for fast headless testing.
+* [**WebDriver**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/WebDriver.md) - uses [webdriverio](http://webdriver.io/) to run tests via WebDriver protocol.
+* [**Protractor**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Protractor.md) - helper empowered by [Protractor](http://protractortest.org/) to run tests via WebDriver protocol.
+* [**TestCafe**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/TestCafe.md) - cheap and fast cross-browser test automation.
+* [**Nightmare**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Nightmare.md) - uses Electron and NightmareJS to run tests.
+* [**Appium**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Appium.md) - for **mobile testing** with Appium
+* [**Detox**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Detox.md) - This is a wrapper on top of Detox library, aimed to unify testing experience for CodeceptJS framework. Detox provides a grey box testing for mobile applications, playing especially well for React Native apps.
And more to come...
@@ -37,8 +41,7 @@ And more to come...
CodeceptJS is a successor of [Codeception](http://codeception.com), a popular full-stack testing framework for PHP.
With CodeceptJS your scenario-driven functional and acceptance tests will be as simple and clean as they can be.
-You don't need to worry about asynchronous nature of NodeJS or about various APIs of Selenium, PhantomJS, Protractor, etc,
-as CodeceptJS unifies them and makes them work as they were synchronous.
+You don't need to worry about asynchronous nature of NodeJS or about various APIs of Selenium, Puppeteer, Protractor, TestCafe, etc. as CodeceptJS unifies them and makes them work as they are synchronous.
## Features
@@ -46,47 +49,46 @@ as CodeceptJS unifies them and makes them work as they were synchronous.
* Designed for scenario driven acceptance testing in BDD-style
* Uses ES6 natively without transpiler.
* Also plays nice with TypeScript.
-* Selenium WebDriver integration using [webdriverio](http://webdriver.io).
* Smart locators: use names, labels, matching text, CSS or XPath to locate elements.
* Interactive debugging shell: pause test at any point and try different commands in a browser.
* Easily create tests, pageobjects, stepobjects with CLI generators.
-
## Install
```sh
-$ npm install -g codeceptjs
+npm install codeceptjs --save
```
Move to directory where you'd like to have your tests (and codeceptjs config) stored, and run
-```
-codeceptjs init
+```sh
+npx codeceptjs init
```
-to create and configure test environment. It is recommended to select WebDriverIO from the list of helpers,
-if you need to write Selenium WebDriver tests.
+to create and configure test environment. It is recommended to select WebDriverIO from the list of helpers, if you need to write Selenium WebDriver tests.
After that create your first test by executing:
-```
-codeceptjs generate:test
+```sh
+npx codeceptjs generate:test
```
Now test is created and can be executed with
-```
-codeceptjs run
+```sh
+npx codeceptjs run
```
If you want to write your tests using TypeScript just generate standard Type Definitions by executing:
-```
-codeceptjs def .
+```sh
+npx codeceptjs def .
```
Later you can even automagically update Type Definitions to include your own custom [helpers methods](docs/helpers.md).
+Note that CodeceptJS requires Node.js version `8.9.1+` or later.
+
## Usage
Learn CodeceptJS by examples. Let's assume we have CodeceptJS installed and WebDriverIO helper enabled.
@@ -94,6 +96,7 @@ Learn CodeceptJS by examples. Let's assume we have CodeceptJS installed and WebD
### Basics
Let's see how we can handle basic form testing:
+
```js
Feature('CodeceptJS Demonstration');
@@ -110,17 +113,17 @@ Scenario('test some forms', (I) => {
```
All actions are performed by I object; assertions functions start with `see` function.
-In this examples all methods of `I` are taken from WebDriverIO helper, see [reference](https://github.com/Codeception/CodeceptJS/blob/master/docs/helpers/WebDriverIO.md) to learn how to use them.
+In this examples all methods of `I` are taken from WebDriver helper, see [reference](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/WebDriver.md) to learn how to use them.
Let's execute this test with `run` command. Additional option `--steps` will show us the running process. We recommend use `--steps` or `--debug` during development.
-```
-codeceptjs run --steps
+```sh
+npx codeceptjs run --steps
```
This will produce an output:
-```
+```sh
CodeceptJS Demonstration --
test some forms
• I am on page "http://simple-form-bootstrap.plataformatec.com.br/documentation"
@@ -140,8 +143,8 @@ Just add `pause()` call at any place in a test and run it.
Interactive shell can be started outside test context by running:
-```
-codeceptjs shell
+```sh
+npx codeceptjs shell
```
### Actions
@@ -176,16 +179,16 @@ In this case 'User is valid' string will be searched only inside elements locate
### Grabbers
In case you need to return a value from a webpage and use it directly in test, you should use methods with `grab` prefix.
-They are expected to be used inside a generator functions, and their results will be available in test:
+They are expected to be used inside async/await functions, and their results will be available in test:
```js
-var assert = require('assert');
+const assert = require('assert');
Feature('CodeceptJS Demonstration');
-Scenario('test page title', function*(I) {
+Scenario('test page title', async (I) => {
I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation');
- var title = yield I.grabTitle();
+ const title = await I.grabTitle();
assert.equal(title, 'Example application with SimpleForm and Twitter Bootstrap');
});
```
@@ -194,7 +197,7 @@ The same way you can grab text, attributes, or form values and use them in next
### Before/After
-Common preperation steps like opening a web page, logging in a user, can be placed in `Before` or `Background`:
+Common preparation steps like opening a web page, logging in a user, can be placed in `Before` or `Background`:
```js
Feature('CodeceptJS Demonstration');
@@ -219,7 +222,7 @@ Scenario('test title', (I) => {
CodeceptJS provides the most simple way to create and use page objects in your test.
You can create one by running
-```
+```sh
codeceptjs generate pageobject
```
@@ -227,16 +230,9 @@ It will create a page object file for you and add it to config.
Let's assume we created one named `docsPage`:
```js
-'use strict';
-
-let I;
+const { I } = inject();
module.exports = {
-
- _init() {
- I = actor();
- },
-
fields: {
email: '#user_basic_email',
password: '#user_basic_password'
@@ -267,14 +263,56 @@ Scenario('test some forms', (I, docsPage) => {
});
```
-## Current State
-
-CodeceptJS is in its early days. Any feedback, issues, and pull requests are welcome. Try it, and if you like it - help us make it better!
+When using typescript, replace `module.exports` with `export` for autocompletion.
+
+
+## Contributing
+
+ - ### [Contributing Guide](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CONTRIBUTING.md)
+ - ### [Code of conduct](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CODE_OF_CONDUCT.md)
+
+
+## Contributors
+
+Thanks all to those who are and will have contributing to this awesome project!
+
+[//]: contributor-faces
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+[//]: contributor-faces
## License
-MIT © [DavertMik](http://codegyre.com)
-
+MIT © [CodeceptJS Team](http://codecept.io)
[npm-image]: https://badge.fury.io/js/codeceptjs.svg
[npm-url]: https://npmjs.org/package/codeceptjs
diff --git a/RoboFile.php b/RoboFile.php
deleted file mode 100644
index 6084e9809..000000000
--- a/RoboFile.php
+++ /dev/null
@@ -1,57 +0,0 @@
-taskGulpRun('docs')
- ->run();
- $this->taskGitStack()
- ->add('docs')
- ->commit('updated docs')
- ->run();
- }
-
- function publishSite()
- {
- $this->taskGitStack()
- ->checkout('site')
- ->merge('master')
- ->run();
- $this->stopOnFail();
- $this->_copy('CHANGELOG.md', 'docs/changelog.md');
- $this->_copy('docker/README.md', 'docs/docker.md');
- $this->_exec('mkdocs gh-deploy');
- $this->_remove('docs/changelog.md');
- $this->taskGitStack()
- ->checkout('master')
- ->run();
- }
-
- function testServer()
- {
- $this->taskServer(8000)
- ->dir('test/data/app')
- ->run();
- }
-
- function release()
- {
- $package = json_decode(file_get_contents('package.json'), true);
- $version = $package['version'];
- $this->docs();
- $this->stopOnFail();
- $this->publishSite();
- $this->taskGitStack()
- ->tag($version)
- ->push('origin master --tags')
- ->run();
-
- $this->_exec('npm publish');
- $this->yell('It is released!');
- }
-}
\ No newline at end of file
diff --git a/bin/codecept.js b/bin/codecept.js
index 3ca800da7..b10873546 100755
--- a/bin/codecept.js
+++ b/bin/codecept.js
@@ -1,21 +1,30 @@
#!/usr/bin/env node
-'use strict';
+const program = require('commander');
+const Codecept = require('../lib/codecept');
+const { print, error } = require('../lib/output');
-var program = require('commander');
-var path = require('path');
-var Config = require('../lib/config');
-var Codecept = require('../lib/codecept');
-var print = require('../lib/output');
-var fileExists = require('../lib/utils').fileExists;
-var fs = require('fs');
+if (process.versions.node && process.versions.node.split('.') && process.versions.node.split('.')[0] < 8) {
+ error('NodeJS >= 8 is required to run.');
+ print();
+ print('Please upgrade your NodeJS engine');
+ print(`Current NodeJS version: ${process.version}`);
+ process.exit(1);
+}
+
+program.usage(' [options]');
+program.version(Codecept.version());
program.command('init [path]')
.description('Creates dummy config in current dir or [path]')
.action(require('../lib/command/init'));
+program.command('migrate [path]')
+ .description('Migrate json config to js config in current dir or [path]')
+ .action(require('../lib/command/configMigrate'));
+
program.command('shell [path]')
.alias('sh')
- .description('Interative shell')
+ .description('Interactive shell')
.option('--verbose', 'output internal logging information')
.option('--profile [value]', 'configuration profile to be used')
.action(require('../lib/command/interactive'));
@@ -26,9 +35,32 @@ program.command('list [path]')
.action(require('../lib/command/list'));
program.command('def [path]')
- .description('List all actions for I.')
+ .description('Generates TypeScript definitions for all I actions.')
+ .option('-c, --config [file]', 'configuration file to be used')
+ .option('-o, --output [folder]', 'target folder to paste definitions')
.action(require('../lib/command/definitions'));
+program.command('gherkin:init [path]')
+ .alias('bdd:init')
+ .description('Prepare CodeceptJS to run feature files.')
+ .option('-c, --config [file]', 'configuration file to be used')
+ .action(require('../lib/command/gherkin/init'));
+
+program.command('gherkin:steps [path]')
+ .alias('bdd:steps')
+ .description('Prints all defined gherkin steps.')
+ .option('-c, --config [file]', 'configuration file to be used')
+ .action(require('../lib/command/gherkin/steps'));
+
+program.command('gherkin:snippets [path]')
+ .alias('bdd:snippets')
+ .description('Generate step definitions from steps.')
+ .option('--dry-run', "don't save snippets to file")
+ .option('-c, --config [file]', 'configuration file to be used')
+ .option('--feature [file]', 'feature files(s) to scan')
+ .option('--path [file]', 'file in which to place the new snippets')
+ .action(require('../lib/command/gherkin/snippets'));
+
program.command('generate:test [path]')
.alias('gt')
.description('Generates an empty test')
@@ -50,7 +82,7 @@ program.command('generate:helper [path]')
.description('Generates a new helper')
.action(require('../lib/command/generate').helper);
-program.command('run [suite] [test]')
+program.command('run [test]')
.description('Executes tests')
// codecept-only options
@@ -59,16 +91,19 @@ program.command('run [suite] [test]')
.option('--verbose', 'output internal logging information')
.option('-o, --override [value]', 'override current config options')
.option('--profile [value]', 'configuration profile to be used')
- .option('--config [file]', 'configuration file to be used')
+ .option('-c, --config [file]', 'configuration file to be used')
+ .option('--features', 'run only *.feature files and skip tests')
+ .option('--tests', 'run only JS test files and skip features')
+ .option('-p, --plugins ', 'enable plugins, comma-separated')
// mocha options
- .option('-c, --colors', 'force enabling of colors')
- .option('-C, --no-colors', 'force disabling of colors')
+ .option('--colors', 'force enabling of colors')
+ .option('--no-colors', 'force disabling of colors')
.option('-G, --growl', 'enable growl notification support')
.option('-O, --reporter-options ', 'reporter-specific options')
.option('-R, --reporter ', 'specify the reporter to use')
- .option('-S, --sort', "sort test files")
- .option('-b, --bail', "bail after first test failure")
+ .option('-S, --sort', 'sort test files')
+ .option('-b, --bail', 'bail after first test failure')
.option('-d, --debug', "enable node's debugger, synonym for node --debug")
.option('-g, --grep ', 'only run tests matching ')
.option('-f, --fgrep ', 'only run tests containing ')
@@ -80,11 +115,113 @@ program.command('run [suite] [test]')
.option('--no-exit', 'require a clean shutdown of the event loop: mocha will not call process.exit')
.option('--recursive', 'include sub directories')
.option('--trace', 'trace function calls')
+ .option('--child ', 'option for child processes')
.action(require('../lib/command/run'));
+program.command('run-rerun [test]')
+ .description('Executes tests in more than one test suite run')
+
+ // codecept-only options
+ .option('--steps', 'show step-by-step execution')
+ .option('--debug', 'output additional information')
+ .option('--verbose', 'output internal logging information')
+ .option('-o, --override [value]', 'override current config options')
+ .option('--profile [value]', 'configuration profile to be used')
+ .option('-c, --config [file]', 'configuration file to be used')
+ .option('--features', 'run only *.feature files and skip tests')
+ .option('--tests', 'run only JS test files and skip features')
+ .option('-p, --plugins ', 'enable plugins, comma-separated')
+
+ // mocha options
+ .option('--colors', 'force enabling of colors')
+ .option('--no-colors', 'force disabling of colors')
+ .option('-G, --growl', 'enable growl notification support')
+ .option('-O, --reporter-options ', 'reporter-specific options')
+ .option('-R, --reporter ', 'specify the reporter to use')
+ .option('-S, --sort', 'sort test files')
+ .option('-b, --bail', 'bail after first test failure')
+ .option('-d, --debug', "enable node's debugger, synonym for node --debug")
+ .option('-g, --grep ', 'only run tests matching ')
+ .option('-f, --fgrep ', 'only run tests containing ')
+ .option('-i, --invert', 'inverts --grep and --fgrep matches')
+ .option('--full-trace', 'display the full stack trace')
+ .option('--compilers :,...', 'use the given module(s) to compile files')
+ .option('--debug-brk', "enable node's debugger breaking on the first line")
+ .option('--inline-diffs', 'display actual/expected differences inline within each string')
+ .option('--no-exit', 'require a clean shutdown of the event loop: mocha will not call process.exit')
+ .option('--recursive', 'include sub directories')
+ .option('--trace', 'trace function calls')
+ .option('--child ', 'option for child processes')
+
+ .action(require('../lib/command/run-rerun'));
+
+program.command('run-workers ')
+ .description('Executes tests in workers')
+ .option('-c, --config [file]', 'configuration file to be used')
+ .option('-g, --grep ', 'only run tests matching ')
+ .option('-i, --invert', 'inverts --grep matches')
+ .option('-o, --override [value]', 'override current config options')
+ .option('--suites', 'parallel execution of suites not single tests')
+ .option('--debug', 'output additional information')
+ .option('--verbose', 'output internal logging information')
+ .option('--features', 'run only *.feature files and skip tests')
+ .option('--tests', 'run only JS test files and skip features')
+ .option('--profile [value]', 'configuration profile to be used')
+ .option('-p, --plugins ', 'enable plugins, comma-separated')
+ .action(require('../lib/command/run-workers'));
+
+program.command('run-multiple [suites...]')
+ .description('Executes tests multiple')
+ .option('-c, --config [file]', 'configuration file to be used')
+ .option('--profile [value]', 'configuration profile to be used')
+ .option('--all', 'run all suites')
+ .option('--features', 'run only *.feature files and skip tests')
+ .option('--tests', 'run only JS test files and skip features')
+ .option('-g, --grep ', 'only run tests matching ')
+ .option('-f, --fgrep ', 'only run tests containing ')
+ .option('-i, --invert', 'inverts --grep and --fgrep matches')
+ .option('--steps', 'show step-by-step execution')
+ .option('--verbose', 'output internal logging information')
+ .option('--debug', 'output additional information')
+ .option('-p, --plugins ', 'enable plugins, comma-separated')
+ .option('-o, --override [value]', 'override current config options')
+ .option('-O, --reporter-options ', 'reporter-specific options')
+ .option('-R, --reporter ', 'specify the reporter to use')
+ .option('--recursive', 'include sub directories')
+
+ // mocha options
+ .option('--colors', 'force enabling of colors')
+
+ .action(require('../lib/command/run-multiple'));
+
+program.command('info [path]')
+ .description('Print debugging information concerning the local environment')
+ .option('-c, --config', 'your config file path')
+ .action(require('../lib/command/info'));
+
+program.command('dry-run [test]')
+ .description('Prints step-by-step scenario for a test without actually running it')
+ .option('-p, --plugins ', 'enable plugins, comma-separated')
+ .option('--bootstrap', 'enable bootstrap script for dry-run')
+ .option('-c, --config [file]', 'configuration file to be used')
+ .option('--all', 'run all suites')
+ .option('--features', 'run only *.feature files and skip tests')
+ .option('--tests', 'run only JS test files and skip features')
+ .option('-g, --grep ', 'only run tests matching ')
+ .option('-f, --fgrep ', 'only run tests containing ')
+ .option('-i, --invert', 'inverts --grep and --fgrep matches')
+ .option('--steps', 'show step-by-step execution')
+ .option('--verbose', 'output internal logging information')
+ .option('--debug', 'output additional information')
+ .action(require('../lib/command/dryRun'));
+
+program.on('command:*', (cmd) => {
+ console.log(`\nUnknown command ${cmd}\n`);
+ program.outputHelp();
+});
+
if (process.argv.length <= 2) {
- console.log('CodeceptJS v' + Codecept.version());
program.outputHelp();
}
program.parse(process.argv);
diff --git a/docker/README.md b/docker/README.md
index 6feddfe5b..44362a70f 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -1,24 +1,34 @@
# Codeceptjs Docker
-CodeceptJS packed into container with the Nightmare, Protractor, and WebDriverIO drivers.
+CodeceptJS packed into container with the Nightmare, Protractor, Puppeteer, and WebDriverIO drivers.
## How to Use
This image comes with the necessary dependencies and packages to execute CodeceptJS tests.
Mount in your CodeceptJS config directory into the `/tests` directory in the docker container.
-Sample mount: `-v path/to/codecept.json:/tests`
+Sample mount: `-v path/to/codecept.conf.js:/tests`
-### Locally
+CodeceptJS runner is available inside container as `codeceptjs`.
+### Locally
-You can execute CodeceptJS with Nightmare locally with no extra configuration.
+You can execute CodeceptJS with Puppeteer or Nightmare locally with no extra configuration.
-```
+```sh
docker run --net=host -v $PWD:/tests codeception/codeceptjs
```
-Nightmare helper must be enabled in codecept.json config.
+To customize execution call `codeceptjs` command:
+
+```sh
+# run tests with steps
+docker run --net=host -v $PWD:/tests codeception/codeceptjs codeceptjs run --steps
+
+# run tests with @user in a name
+docker run --net=host -v $PWD:/tests codeception/codeceptjs codeceptjs run --grep "@user"
+```
+
### Docker Compose
@@ -77,5 +87,51 @@ _Note: If running with the Nightmare driver, it is not necessary to run a seleni
To build this image:
```sh
-$ docker build -t codeception/codeceptjs .
-```
\ No newline at end of file
+docker build -t codeception/codeceptjs .
+```
+
+* this directory will be added as `/codecept` insde container
+* tests directory is expected to be mounted as `/tests`
+* `codeceptjs` is a synlink to `/codecept/bin/codecept.js`
+
+To build this image with your desired Node version:
+
+```sh
+docker build -t codeception/codeceptjs . --build-arg NODE_VERSION=12.10.0
+```
+
+### Passing Options
+
+Options can be passed by calling `codeceptjs`:
+
+```
+docker run -v $PWD:/tests codeception/codeceptjs codeceptjs run --debug
+```
+
+Alternatively arguments to `codecept run` command can be passed via `CODECEPT_ARGS` environment variable. For example to run your tests with debug
+output:
+
+```yaml
+version: '2'
+services:
+ codeceptjs:
+ image: codeception/codeceptjs
+ environment:
+ - CODECEPT_ARGS=--debug
+ volumes:
+ - .:/tests
+```
+
+You can also use `run-workers`to run tests by passing `NO_OF_WORKERS`, additionally, you can pass more params like showing the debug info as the following example:
+
+```yaml
+version: '2'
+services:
+ codeceptjs:
+ image: codeception/codeceptjs
+ environment:
+ - NO_OF_WORKERS=3
+ - CODECEPT_ARGS=--debug
+ volumes:
+ - .:/tests
+```
diff --git a/docker/entrypoint b/docker/entrypoint
index 8d30cfdad..0e313dc8a 100755
--- a/docker/entrypoint
+++ b/docker/entrypoint
@@ -1,8 +1,4 @@
#!/usr/bin/env bash
set -e
-# Start Xvfb
-Xvfb -ac -screen scrn 1280x1024x24 :9.0 &
-export DISPLAY=:9.0
-
-exec "$@"
\ No newline at end of file
+xvfb-run -a --server-args="-screen 0 1024x768x24" "$@"
diff --git a/docker/run.sh b/docker/run.sh
index 697005455..cd9c41bc7 100755
--- a/docker/run.sh
+++ b/docker/run.sh
@@ -1,13 +1,28 @@
#!/usr/bin/env bash
-source /docker/help.sh
+source /codecept/docker/help.sh
# Check if tests are correctly mounted
if [[ -d "/tests/" ]]; then
- echo "CodeceptJS directory has been found."
+ echo "CodeceptJS directory has been found."
- # Run the tests
- node bin/codecept.js run /tests/ $GREP
+ # Run the tests
+ cd /tests/ || exit
+ if [ "$RUN_MULTIPLE" = true ]; then
+ echo "Tests are split into chunks and executed in multiple processes."
+ if [ ! "$CODECEPT_ARGS" ]; then
+ echo "No CODECEPT_ARGS provided. Tests will procceed with --all option to run all configured runs"
+ codeceptjs run-multiple --all
+ else
+ codeceptjs run-multiple $CODECEPT_ARGS
+ fi
else
- display_usage
-fi
\ No newline at end of file
+ if [ ! "$NO_OF_WORKERS" ]; then
+ codeceptjs run $CODECEPT_ARGS
+ else
+ codeceptjs run-workers $NO_OF_WORKERS $CODECEPT_ARGS
+ fi
+ fi
+else
+ display_usage
+fi
diff --git a/docs/acceptance.md b/docs/acceptance.md
deleted file mode 100644
index 69f3d9d0d..000000000
--- a/docs/acceptance.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# Acceptance Testing
-
-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.
-
-By default CodeceptJS uses [WebDriverIO](/helpers/WebDriverIO/) 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 [SeleniumWebdriver](/helpers/SeleniumWebdriver) 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.
-
-That is what a test look like.
-
-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.
-
-```js
-I.amOnPage('/login');
-I.fillField('Username', 'john');
-I.fillField('Password', '123456');
-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.
-
-## Locating Element
-
-Element can be found by CSS or XPath locators. Practically every steps
-in WebDriverIO helper accept them both.
-
-```js
-I.seeElement('.user'); // element with CSS class user
-I.seeElement('//button(contains(., "press me")]'); // button
-```
-
-By default CodeceptJS tries to guess the locator type.
-In order to specify exact locator type you can pass a hash called **strict locator**.
-
-```js
-I.seeElement({css: 'div.user'});
-I.seeElement({xpath: '//div[@class=user]'});
-```
-
-Strict locators allow to specify additional locator types:
-
-```js
-// locate form element by name
-I.seeElement({name: 'password'});
-// locate element by text
-I.seeElement({text: 'press me'});
-// locate element by id
-I.seeElement({id: 'users'});
-```
-
-## Clicking
-
-CodeceptJS provides a flexible syntax to specify an element to click.
-
-By default CodeceptJS tries to find button or link with exact text on it
-
-```js
-// search for link or button
-I.click('Login');
-```
-
-If none found, CodeceptJS tries to find link or button containing that text. In case an image is clickable its `alt` attribute will be checked for text inclusion. Form buttons will also be searched by name.
-
-To narrow down the results you can specify a context in second parameter.
-
-```js
-I.click('Login', '.nav'); // search only in .nav
-I.click('Login', {css: 'footer'}); // search only in footer
-```
-
-To skip the global search pass exact strict locator (or start locator with `//` or `.` or `#`).
-In this case you are not limited to buttons and links. Any element found by that locator is clicked.
-
-```js
-// click element by CSS
-I.click('#signup');
-// click element located by name inside a form
-I.click({name: 'submit'}, '#user>form');
-```
-
-## Filling Fields
-
-Clicking the links is not what takes the most time during testing a web site. If your site consists only of links you can skip test automation. The most routine waste of time goes into the testing of forms. CodeceptJS provides several ways of doing that.
-
-Let's submit this sample form for a test:
-
-```html
-
-```
-
-We need to fill in all those fields and click "Update" button. CodeceptJS matches form elements by their label, name, or by CSS or XPath locators.
-
-```js
-// we are using label to match user_name field
-I.fillField('Name', 'Miles');
-// we can use input name
-I.fillField('user[email]','miles@davis.com');
-// select element by label, choose option by text
-I.selectOption('Gender','Male');
-// click 'Update' button, found by text
-I.click('Update');
-```
-
-Alternative scenario:
-
-```js
-// we are using CSS
-I.fillField('#user_name', 'Miles');
-I.fillField('#user_email','miles@davis.com');
-// select element by label, option by value
-I.selectOption('#user_gender','m');
-// click 'Update' button, found by name
-I.click('submitButton', '#update_form');
-```
-
-## Assertions
-
-In order to verify the expected behavior of a web application, web page connects should be checked.
-CodeceptJS provides built-in assertions for that. They start with `see` (or `dontSee`) prefix, as they describe user's current vision.
-
-The most general and common assertion is `see`:
-
-```js
-// Just a visible text on a page
-I.see('Hello');
-// text inside .msg element
-I.see('Hello', '.msg');
-// opposite
-I.dontSee('Bye');
-```
-
-You should provide a text as first argument, and optionally a locator to narrow the search context.
-
-You can check that specific element exists (or not) on a page, as it was described in [Locating Element](#locating-element) section.
-
-```js
-I.seeElement('.notice');
-I.dontSeeElement('.error');
-```
-
-Additional assertions:
-
-```js
-I.seeInCurrentUrl('/user/miles');
-I.seeInField('user[name]', 'Miles');
-I.seeInTitle('My Website');
-```
-
-To see all possible assertions see the helper's reference.
-
-## Grabbing
-
-Sometimes you need to retrieve a data from a page to use it in next steps of a scenario.
-Imagine, application generates a password and you want to ensure that user can login using this password.
-
-```js
-I.fillField('email', 'miles@davis.com')
-I.click('Generate Password');
-$password = yield I.grabTextFrom('#password');
-I.click('Login');
-I.fillField('email', 'miles@davis.com');
-I.fillField('password', $password);
-I.click('Log in!');
-```
-
-`grabTextFrom` action is used here to retrieve text from an element. All actions starting with `grab` prefix are expected to return data. In order to synchronize this step with a scenario you should pause test execution with `yield` keyword of ES6. To make it work your test should be written inside a generator function (notice `*` in its definition):
-
-```js
-Scenario('use page title', function*(I) {
- // ...
- var password = yield I.grabTextFrom('#password');
- I.fillField('password', password);
-});
-```
-
-## Waiting
-
-In modern web applications rendering is happen on client side.
-Sometimes that may cause delays. A test may fail while trying to click an element which has not appeared on a page yet.
-To handle this cases `wait*` methods introduced.
-
-```js
-I.waitForElement('#agree_button', 30); // secs
-// clicks a button only when it is visible
-I.click('#agree_button');
-```
-
-More wait actions can be found in helper's reference.
-
----
-
-### done()
-
-CodeceptJS through helpers provides user friendly API to interact with a webpage. In this section we described using WebDriverIO helper which allows to control browser through Selenium WebDriver.
diff --git a/docs/advanced.md b/docs/advanced.md
new file mode 100644
index 000000000..dfb661950
--- /dev/null
+++ b/docs/advanced.md
@@ -0,0 +1,293 @@
+---
+permalink: /advanced
+title: Advanced Usage
+---
+
+# 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
+
+```js
+Scenario('update user profile @slow')
+```
+
+Alternativly, use `tag` method of Scenario to set additional tags:
+
+```js
+Scenario('update user profile', () => {
+ // test goes here
+}).tag('@slow').tag('important');
+```
+
+All tests with `@tag` could be executed with `--grep '@tag'` option.
+
+```sh
+codeceptjs run --grep '@slow'
+```
+
+Use regex for more flexible filtering:
+
+* `--grep '(?=.*@smoke2)(?=.*@smoke3)'` - run tests with @smoke2 and @smoke3 in name
+* `--grep "\@smoke2|\@smoke3"` - run tests with @smoke2 or @smoke3 in name
+* `--grep '((?=.*@smoke2)(?=.*@smoke3))|@smoke4'` - run tests with (@smoke2 and @smoke3) or @smoke4 in name
+* `--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"
+}
+```
+
+
+## Test Options
+
+Features and Scenarios have their options that can be set by passing a hash after their names:
+
+```js
+Feature('My feature', {key: val});
+
+Scenario('My scenario', {key: val}, (I) => {});
+```
+
+You can use this options for build your own [plugins](https://codecept.io/hooks/#plugins) with [event listners](https://codecept.io/hooks/#api). Example:
+
+```js
+ // for test
+ event.dispatcher.on(event.test.before, (test) => {
+ ...
+ if (test.opts.key) {
+ ...
+ }
+ ...
+ });
+ // or for suite
+ event.dispatcher.on(event.suite.before, (suite) => {
+ ...
+ if (suite.opts.key) {
+ ...
+ }
+ ...
+ });
+```
+
+### Timeout
+
+By default there is no timeout for tests, however you can change this value for a specific suite:
+
+```js
+Feature('Stop me').timeout(5000); // set timeout to 5s
+```
+
+or for the test:
+
+```js
+// set timeout to 1s
+Scenario("Stop me faster", (I) => {
+ // test goes here
+}).timeout(1000);
+
+// alternative
+Scenario("Stop me faster", {timeout: 1000}, (I) => {});
+
+// disable timeout for this scenario
+Scenario("Don't stop me", {timeout: 0}, (I) => {});
+```
+
+
+## Dynamic Configuration
+
+Helpers can be reconfigured per scenario or per feature.
+This might be useful when some tests should be executed with different settings than others.
+In order to reconfigure tests use `.config()` method of `Scenario` or `Feature`.
+
+```js
+Scenario('should be executed in firefox', (I) => {
+ // I.amOnPage(..)
+}).config({ browser: 'firefox' })
+```
+
+In this case `config` overrides current config of the first helper.
+To change config of specific helper pass two arguments: helper name and config values:
+
+```js
+Scenario('should create data via v2 version of API', (I) => {
+ // I.amOnPage(..)
+}).config('REST', { endpoint: 'https://api.mysite.com/v2' })
+```
+
+Config can also be set by a function, in this case you can get a test object and specify config values based on it.
+This is very useful when running tests against cloud providers, like BrowserStack. This function can also be asynchronous.
+
+```js
+Scenario('should report to BrowserStack', (I) => {
+ // I.amOnPage(..)
+}).config((test) => {
+ return { desiredCapabilities: {
+ project: test.suite.title,
+ name: test.title,
+ }}
+});
+```
+
+Config changes can be applied to all tests in suite:
+
+```js
+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.
+
+
+### Rerunning Flaky Tests Multiple Times
+
+End to end tests can be flaky for various reasons. Even when we can't do anything to solve this problem it we can do next two things:
+
+* Detect flaky tests in our suite
+* Fix flaky tests by rerunning them.
+
+Both tasks can be achieved with [`run-rerun` command](/commands/#run-rerun) which runs tests multiple times until all tests are passed.
+
+You should set min and max runs boundaries so when few tests fail in a row you can rerun them until they are succeeded.
+
+```js
+// inside to codecept.conf.js
+exports.config = { // ...
+ rerun: {
+ // run 4 times until 1st success
+ minSuccess: 1,
+ maxReruns: 4,
+ }
+}
+```
+
+If you want to check all your tests for stability you can set high boundaries for minimal success:
+
+```js
+// inside to codecept.conf.js
+exports.config = { // ...
+ rerun: {
+ // run all tests must pass exactly 5 times
+ minSuccess: 5,
+ maxReruns: 5,
+ }
+}
+```
+
+Now execute tests with `run-rerun` command:
+
+```
+npx codeceptjs run-rerun
+```
+
diff --git a/docs/angular.md b/docs/angular.md
index 625f7ac84..b61ddf4e4 100644
--- a/docs/angular.md
+++ b/docs/angular.md
@@ -1,23 +1,28 @@
-## AngularJS E2E Testing with CodeceptJS
+---
+permalink: /angular
+title: Testing with Protractor
+---
-### Introduction
+# Protractor Testing with CodeceptJS
-CodeceptJS is an acceptance testing framework. In diversified world of JavaScript testing libraries it aims to create a unified high level API for end-to-end testing, powered by differnet backends.
-CodeceptJS allows you to write a test and switch in config execution drivers: will it be *wedriverio*, *selenium-webdriver*, or *protractor* depends on you.
-This way you aren't be bound to implementation, and your acceptance tests will work no matter of framework running them.
+## Introduction
-As you know, [Protractor](http://www.protractortest.org/#/) is an official tool for testing AngularJS applications.
-CodeceptJS should not be considerend as alternative to Protractor but a testing framework utilizing this powerful library.
+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 a variety of backends.
+CodeceptJS allows you to write a test and switch the execution driver via config: whether it's *wedriverio*, *puppeteer*, or *protractor* depends on you.
+This way you aren't bound to a specific implementation, and your acceptance tests will work no matter what framework is running them.
-
+[Protractor](http://www.protractortest.org/#/) is an official tool for testing AngularJS applications.
+CodeceptJS should not be considered as alternative to Protractor, but rather a testing framework that leverages this powerful library.
-So there is no magic in testing of AngularJS application in CodeceptJS.
-You just execute regular Protractor commands, packed in a simple high-level API.
+
-
+There is no magic in testing of AngularJS application in CodeceptJS.
+You just execute regular Protractor commands, packaged into a simple, high-level API.
-As an example we will use popular [TodoMVC application](http://todomvc.com/examples/angularjs/#/).
-How would we test creating a new todo item in CodeceptJS?
+
+
+As an example, we will use the popular [TodoMVC application](http://todomvc.com/examples/angularjs/#/).
+How would we test creating a new todo item using CodeceptJS?
```js
Scenario('create todo item', (I) => {
@@ -30,7 +35,7 @@ Scenario('create todo item', (I) => {
});
```
-The similar test written in native syntax of Protractor (inherited from selenium-webdriver) would look like this:
+A similar test written using Protractor's native syntax (inherited from selenium-webdriver) would look like this:
```js
it('should create todo item', (I) => {
@@ -45,16 +50,15 @@ it('should create todo item', (I) => {
});
```
-Comparing to the API proposed by CodeceptJS, this code looks a bit more complicated.
-But what the more important, it's really really hard to read and follow its logic.
-Readability is the most crucial part in acceptance testing.
-You should easily change tests when changes specification or design.
-Probably, only a person who writes Protractor tests in your company,
-could do those changes, while CodeceptJS allows anyone to work with tests.
-Contrary, CodeceptJS provides CodeceptJS provides scenario-driven approach, so test is just a step-by-step representation of real user actions.
-This way you can easily read, and follow test scenario, and edit it when you need it to be changed.
+Compared to the API proposed by CodeceptJS, the Protractor code looks more complicated.
+Even more important, it's harder to read and follow the logic of the Protractor test.
+Readability is a crucial part of acceptance testing.
+Tests should be easy to modify when there are changes in the specification or design.
+If the test is written in Protractor, it would likely require someone familiar with Protractor to make the change, whereas CodeceptJS allows anyone to understand and modify the test.
+CodeceptJS provides scenario-driven approach, so a test is just a step-by-step representation of real user actions.
+This means you can easily read and understand the steps in a test scenario, and edit the steps when the test needs to be changed.
-In this way CodeceptJS is more similar to Cucumber, so if you run a test with `--steps` option you will see this output:
+In this way, CodeceptJS is similar to Cucumber. If you run a test with `--steps` option you will see this output:
```bash
TodoMvc --
@@ -68,67 +72,99 @@ TodoMvc --
✓ OK in 968ms
```
-Unlike Cucumber, CodeceptJS is not about writing test scenarios above for business rules.
-To say it again, its **goal is to provide standard action steps you can use for testing applications**.
-Surely, it can't cover 100% of cases but it aims for 90%, for others you can write your own steps inside a [custom Helper](http://codecept.io/helpers/) using API of Protractor
+Unlike Cucumber, CodeceptJS is not about writing test scenarios to satisfy business rules or requirements.
+Instead, its **goal is to provide standard action steps you can use for testing applications**.
+Although it can't cover 100% of use cases, CodeceptJS aims for 90%. For the remainder, you can write your own steps inside a [custom Helper](http://codecept.io/helpers/) using Protractor's 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.
+To start using CodeceptJS you will need to install it via NPM and initialize it in a directory with tests.
```bash
-npm install -g codeceptjs
-codeceptjs init
+npm install codeceptjs --save
+npx codeceptjs init
```
-You will be asked questions about initial configuration, make sure you select Protractor helper.
-If you didn't have Protracotr library it **will be installed**.
-Please agree to extend steps, and use `http://todomvc.com/examples/angularjs/` as a url for Protractor helper.
-
-For TodoMVC application you will have following config created in `codecept.json` file:
-
-```json
-{
- "tests": "./*_test.js",
- "timeout": 10000,
- "output": "./output",
- "helpers": {
- "Protractor": {
- "url": "http://todomvc.com/examples/angularjs/",
- "driver": "hosted",
- "browser": "firefox",
- "rootElement": "body"
- }
- },
- "include": {
- "I": "./steps_file.js"
- },
- "bootstrap": false,
- "mocha": {},
- "name": "todoangular"
+You will be asked questions about the initial configuration, make sure you select the Protractor helper.
+If your project didn't already have the Protractor library, it **will be installed** as part of this process.
+Please agree to extend steps, and use `http://todomvc.com/examples/angularjs/` as the url for Protractor helper.
+
+For TodoMVC application, you will have following config created in the `codecept.conf.js` file:
+
+```js
+exports.config = { tests: './*_test.js',
+ timeout: 10000,
+ output: './output',
+ helpers:
+ { Protractor:
+ { url: 'http://todomvc.com/examples/angularjs/',
+ driver: 'hosted',
+ browser: 'chrome',
+ rootElement: 'body' } },
+ include: { I: './steps_file.js' },
+ bootstrap: false,
+ mocha: {},
+ name: 'todoangular'
}
```
-First test can be generated with `gt` command:
+Your first test can be generated with the `gt` command:
```bash
-codeceptjs gt
+npx 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.
-You can also run `list` command to see methods of I:
+After that, you can start writing your first CodeceptJS/Angular tests.
+Please refer to the [Protractor helper](http://codecept.io/helpers/Protractor/) documentation for a list of all available actions.
+You can also run the `list` command to see methods of I:
```bash
-codeceptjs list
+npx codeceptjs list
```
-### Writing First Test
+## Starting Selenium Server
+
+Protractor requires Selenium Server to be started and running. To start and stop Selenium automatically install `@wdio/selenium-standalone-service`.
-Test scenario should always use `I` object to execute commands.
-This is important as all methods of `I` are running in global promise chain, this way CodeceptJS makes sure everything is executed in right order.
-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:
+```
+npm i @wdio/selenium-standalone-service --save
+```
+
+Enable it in the `codecept.conf.js` file, inside the plugins section:
+
+```js
+exports.config = {
+ // ...
+ // inside codecept.conf.js
+ plugins: {
+ wdio: {
+ enabled: true,
+ services: ['selenium-standalone']
+ }
+ }
+}
+```
+
+## Testing non-Angular Applications
+
+Protractor can also be used to test applications built without AngularJS. In this case, you need to disable the angular synchronization feature inside the config:
+
+```js
+helpers: {
+ Protractor: {
+ url: "http://todomvc.com/examples/angularjs/",
+ driver: "hosted",
+ browser: "firefox",
+ angular: false
+ }
+}
+```
+
+## Writing Your First Test
+
+Your test scenario should always use the `I` object to execute commands.
+This is important, as all methods of `I` are running in the global promise chain. This way, CodeceptJS makes sure everything is executed in right order.
+To start with opening a webpage, use the `amOnPage` command for. Since we already specified the full URL to the TodoMVC app, we can pass the relative path for our url, instead of the absolute url:
```js
Feature('Todo MVC');
@@ -138,7 +174,7 @@ Scenario('create todo item', (I) => {
});
```
-All scenarios should describe actions on site and assertions taken in the end. In CodeceptJS assertion commands have `see` or `dontSee` prefix:
+All scenarios should describe actions on the site, with assertions at the end. In CodeceptJS, assertion commands have the `see` or `dontSee` prefix:
```js
Feature('Todo MVC');
@@ -149,12 +185,13 @@ Scenario('create todo item', (I) => {
});
```
-A test can be executed with `run` command, we recommend to use `--steps` options to follow step-by-step execution:
+A test can be executed with the `run` command, we recommend using the `--steps` option to print out the step-by-step execution:
+```sh
+npx codeceptjs run --steps
```
-$ codeceptjs run --steps
-CodeceptJS v0.3.2
+```
Test root is assumed to be /home/davert/demos/todoangular
Using the selenium server at http://localhost:4444/wd/hub
@@ -164,13 +201,12 @@ TodoMvc --
• I dont see element "#todo-count"
```
-### Running Several Scenarios
+## Running Several Scenarios
-By writing a test in similar manner we will have a test shown in the beginning of this guide. Probably we would like not to finish with one test,
-but have more, for testing editing of todo items, checking todo items, and more.
+By now, you should have a test similar to the one shown in the beginning of this guide. We probably want to have multiple tests though, like testing the editing of todo items, checking todo items, etc.
-Let's prepare our test for multiple scenarios. All test scenarios will need to open main page of application, so `amOnPage` can be moved into the `Before` hook:
-Scenarios will probably deal with created todo items, so we can move logic of crating new todo into a function.
+Let's prepare our test to contain multiple scenarios. All of our test scenarios will need to to start with with the main page of application open, so `amOnPage` can be moved into the `Before` hook:
+Our scenarios will also probably deal with created todo items, so we can move the logic of creating a new todo into a function.
```js
Feature('TodoMvc');
@@ -179,7 +215,7 @@ Before((I) => {
I.amOnPage('/');
});
-var createTodo = function (I, name) {
+const createTodo = function (I, name) {
I.fillField({model: 'newTodo'}, name);
I.pressKey('Enter');
}
@@ -192,7 +228,7 @@ Scenario('create todo item', (I) => {
});
```
-and so we can add even more tests!
+and now we can add even more tests!
```js
Scenario('edit todo', (I) => {
@@ -213,31 +249,33 @@ Scenario('check todo item', (I) => {
});
```
-### Locators
+> This example is [available on GitHub](https://github.com/DavertMik/codeceptjs-angular-todomvc).
-Like you may have noticed, CodeceptJS doesn't use `by.*` locators similar to Protractor or Selenium Webdriver.
-Instead most of methods expect you to pass valid CSS or XPath. In case you don't want CodeceptJS to guess the type of locator,
-you can specify them using so-called strict locators. This is an absolute analogy of `by`, so you can use angular specific locators (like models, repeaters, bindings, etc) in it:
-```
+## Locators
+
+You may have noticed that CodeceptJS doesn't use `by.*` locators which are common in Protractor or Selenium Webdriver.
+Instead, most methods expect you to pass valid CSS selectors or XPath. If you don't want CodeceptJS to guess the locator type, then you can specify the type using *strict locators*. This is the CodeceptJS version of `by`, so you can also reuse your angular specific locators (like models, repeaters, bindings, etc):
+
+```sh
{css: 'button'}
{repeater: "todo in todos"}
{binding: 'latest'}
```
-When we deal with clicks, CodeceptJS can take a text and search a web page for a valid clickable element with that text.
-So links and buttons can be searched by their text.
-Same thing happens for form fields: they are searched by field names, labels, and so on.
+When dealing with clicks, we can specify a text value. CodeceptJS will use that value to search the web page for a valid clickable element containing our specified text.
+This enables us to search for links and buttons by their text.
-Using such smart locators makes tests easy to write, however, searching an element by text is slower than using CSS|XPath and much slower than using strict locators.
+The same is true for form fields: they can be searched by field name, label, and so on.
-### Refactoring
+Using smart locators makes tests easier to write, however searching an element by text is slower than searching via CSS|XPath, and is much slower than using strict locators.
-In previous examples, we've moved actions into `createTodo` function. Is there a more elegant way of refactoring?
-Can we have something like `I.createTodo()` to be used in code? Sure, we can do so by editing `steps_file.js` created by init command.
+## Refactoring
+
+In the previous examples, we moved actions into the `createTodo` function. Is there a more elegant way of refactoring?
+Can we instead write a function like `I.createTodo()` which we can reuse? In fact, we can do so by editing the `steps_file.js` file created by the init command.
```js
-'use strict';
// in this file you can append custom step methods to 'I' object
module.exports = function() {
@@ -249,7 +287,8 @@ module.exports = function() {
});
}
```
-And that's all, method is available to use as `I.createTodo(title)`:
+
+That's it, our method is now available to use as `I.createTodo(title)`:
```js
Scenario('create todo item', (I) => {
@@ -262,13 +301,13 @@ Scenario('create todo item', (I) => {
To learn more about refactoring options in CodeceptJS read [PageObjects guide](http://codecept.io/pageobjects/).
-### Extending
-What if CodeceptJS doesn't provide some of Protractor functionality you actually need? Sure its API is to general,
-and this case is possible. If you don't know how to do something with CodeceptJS - revert back to Protractor syntax!
+## Extending
+
+What if CodeceptJS doesn't provide some specific Protractor functionality you need? If you don't know how to do something with CodeceptJS, you can simply revert back to using Protractor syntax!
-Create custom helper, define methods for it, and use it inside the I object. Your Helper can access `browser` from Protractor
-by accessing Protractor helper:
+Create a custom helper, define methods for it, and use it inside the I object. Your Helper can access `browser` from Protractor
+by accessing the Protractor helper:
```js
let browser = this.helpers['Protractor'].browser;
@@ -280,9 +319,7 @@ or use global `element` and `by` variables to locate elements:
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).
+This is the recommended way to implement all custom logic using low-level Protractor syntax in order to reuse it inside of test scenarios.
+For more information, see an [example of such a 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
diff --git a/docs/basics.md b/docs/basics.md
index 0f4eb0a52..8fcb72e03 100644
--- a/docs/basics.md
+++ b/docs/basics.md
@@ -1,6 +1,11 @@
-# Basics
+---
+permalink: /basics
+title: Getting Started
+---
+
+# Getting Started
-CodeceptJS is a modern end to end testing framework with a special BDD-style syntax. The test is written as a linear scenario of user's action on a site.
+CodeceptJS is a modern end to end testing framework with a special BDD-style syntax. The tests are written as a linear scenario of the user's action on a site.
```js
Feature('CodeceptJS demo');
@@ -8,65 +13,571 @@ Feature('CodeceptJS demo');
Scenario('check Welcome page on site', (I) => {
I.amOnPage('/');
I.see('Welcome');
-})
+});
```
-Tests are expected to be written in ECMAScript 6.
-Each test is described inside a `Scenario` function with `I` object passed into it.
-I object is an **actor**, an abstraction for a testing user. I is a proxy object for currently enabled **Helpers**.
+Tests are expected to be written in **ECMAScript 7**.
-```json
- "helpers": {
- "WebDriverIO": {
- "url": "http://localhost",
- "browser": "firefox"
- }
- }
+Each test is described inside a `Scenario` function with the `I` object passed into it.
+The `I` object is an **actor**, an abstraction for a testing user. The `I` is a proxy object for currently enabled **Helpers**.
+
+## Architecture
+
+CodeceptJS bypasses execution commands to helpers. Depending on the helper enabled, your tests will be executed differently. If you need cross-browser support you should choose Selenium-based WebDriver or TestCafé. If you are interested in speed - you should use Chrome-based Puppeteer.
+
+The following is a diagram of the CodeceptJS architecture:
+
+
+
+All helpers share the same API, so it's easy to migrate tests from one backend to another.
+However, because of the difference in backends and their limitations, they are not guaranteed to be compatible with each other. For instance, you can't set request headers in WebDriver or Protractor, but you can do so in Puppteer or Nightmare.
+
+**Pick one helper, as it defines how tests are executed.** If requirements change it's easy to migrate to another.
+
+---
+
+Refer to following guides to more information on:
+
+* [▶ WebDriver](/webdriver)
+* [▶ Protractor](/angular)
+* [▶ Puppeteer](/puppeteer)
+* [▶ Playwright](/playwright)
+* [▶ Nightmare](/nightmare)
+* [▶ TestCafe](/testcafe)
+
+> ℹ Depending on a helper selected a list of available actions may change.
+
+To list all available commands for the current configuration run `codeceptjs list`
+or enable [auto-completion by generating TypeScript definitions](#intellisense).
+
+
+## Writing Tests
+
+Tests are written from a user's perspective. There is an actor (represented as `I`) which contains actions taken from helpers. A test is written as a sequence of actions performed by an actor:
+
+```js
+I.amOnPage('/');
+I.click('Login');
+I.see('Please Login', 'h1');
+// ...
+```
+
+### Opening a Page
+
+A test should usually start by navigating the browser to a website.
+
+Start a test by opening a page. Use the `I.amOnPage()` command for this:
+
+```js
+// When "http://site.com" is url in config
+I.amOnPage('/'); // -> opens http://site.com/
+I.amOnPage('/about'); // -> opens http://site.com/about
+I.amOnPage('https://google.com'); // -> https://google.com
+```
+
+When an URL doesn't start with a protocol (http:// or https://) it is considered to be a relative URL and will be appended to the URL which was initially set-up in the config.
+
+> It is recommended to use a relative URL and keep the base URL in the config file, so you can easily switch between development, stage, and production environments.
+
+
+### Locating Element
+
+Element can be found by CSS or XPath locators.
+
+```js
+I.seeElement('.user'); // element with CSS class user
+I.seeElement('//button[contains(., "press me")]'); // button
+```
+
+By default CodeceptJS tries to guess the locator type.
+In order to specify the exact locator type you can pass an object called **strict locator**.
+
+```js
+I.seeElement({css: 'div.user'});
+I.seeElement({xpath: '//div[@class=user]'});
+```
+
+Strict locators allow to specify additional locator types:
+
+```js
+// locate form element by name
+I.seeElement({name: 'password'});
+// locate element by React component and props
+I.seeElement({react: 'user-profile', props: {name: 'davert'}});
+```
+
+In [mobile testing](http://codecept.io/mobile/#locating-elements) you can use `~` to specify the accessibility id to locate an element. In web application you can locate elements by their `aria-label` value.
+
+```js
+// locate element by [aria-label] attribute in web
+// or by accessibility id in mobile
+I.seeElement('~username');
+```
+
+> [▶ Learn more about using locators in CodeceptJS](/locators).
+
+### Clicking
+
+CodeceptJS provides a flexible syntax to specify an element to click.
+
+By default CodeceptJS tries to find the button or link with the exact text on it
+
+```js
+// search for link or button
+I.click('Login');
```
-For current config all methods of `I` will be taken from `WebDriverIO` helper.
-This is done to allow easy switching of running backends so you could replace WebDriverIO with Protractor or Nightmare helpers.
+If none was found, CodeceptJS tries to find a link or button containing that text. In case an image is clickable its `alt` attribute will be checked for text inclusion. Form buttons will also be searched by name.
+
+To narrow down the results you can specify a context in the second parameter.
+
+```js
+I.click('Login', '.nav'); // search only in .nav
+I.click('Login', {css: 'footer'}); // search only in footer
+```
+
+> To skip guessing the locator type, pass in a strict locator - A locator starting with '#' or '.' is considered to be CSS. Locators starting with '//' or './/' are considered to be XPath.
+
+You are not limited to buttons and links. Any element can be found by passing in valid CSS or XPath:
+
+```js
+// click element by CSS
+I.click('#signup');
+// click element located by special test-id attribute
+I.click('//dev[@test-id="myid"]');
+```
+
+> ℹ If click doesn't work in a test but works for user, it is possible that frontend application is not designed for automated testing. To overcome limitation of standard click in this edgecase use `forceClick` method. It will emulate click instead of sending native event. This command will click an element no matter if this element is visible or animating. It will send JavaScript "click" event to it.
+
+### Filling Fields
+
+Clicking the links is not what takes the most time during testing a web site. If your site consists only of links you can skip test automation. The most waste of time goes into the testing of forms. CodeceptJS provides several ways of doing that.
+
+Let's submit this sample form for a test:
+
+
+
+```html
+
+```
+
+We need to fill in all those fields and click the "Update" button. CodeceptJS matches form elements by their label, name, or by CSS or XPath locators.
+
+```js
+// we are using label to match user_name field
+I.fillField('Name', 'Miles');
+// we can use input name
+I.fillField('user[email]','miles@davis.com');
+// select element by label, choose option by text
+I.selectOption('Role','Admin');
+// click 'Save' button, found by text
+I.checkOption('Accept');
+I.click('Save');
+```
+
+> ℹ `selectOption` works only with standard `
";
+ echo "You entered {$_SERVER['PHP_AUTH_PW']} as your password.
";
+}
+?>
\ No newline at end of file
diff --git a/test/data/app/view/form/aria.php b/test/data/app/view/form/aria.php
new file mode 100644
index 000000000..3a9a56495
--- /dev/null
+++ b/test/data/app/view/form/aria.php
@@ -0,0 +1,136 @@
+
+
+
+ Accessibility
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/data/app/view/form/css_colors.php b/test/data/app/view/form/css_colors.php
new file mode 100644
index 000000000..d7773bb96
--- /dev/null
+++ b/test/data/app/view/form/css_colors.php
@@ -0,0 +1,41 @@
+
+
+
+
+ CSS Color Properties
+
+
+
+
+
+CSS Color Properties
+Blue Header
+Header using hex code
+Header using rgb
+Header using rgba
+
+
+
+
+
+
diff --git a/test/data/app/view/form/custom_locator.php b/test/data/app/view/form/custom_locator.php
new file mode 100644
index 000000000..d7ffadd1e
--- /dev/null
+++ b/test/data/app/view/form/custom_locator.php
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+Step One Button
+Step Two Button
+Step Three Button
+Steps Complete!
+
+
+
+
+
diff --git a/test/data/app/view/form/doubleclick.php b/test/data/app/view/form/doubleclick.php
index bd8cba7cc..5e550cfb1 100644
--- a/test/data/app/view/form/doubleclick.php
+++ b/test/data/app/view/form/doubleclick.php
@@ -9,6 +9,7 @@
color: white;
height: 100px;
width: 150px;
+ user-select: text;
}
div.dbl {
background: yellow;
diff --git a/test/data/app/view/form/download.php b/test/data/app/view/form/download.php
new file mode 100644
index 000000000..c65aea963
--- /dev/null
+++ b/test/data/app/view/form/download.php
@@ -0,0 +1,8 @@
+
+
+
+
+Download file
+
+
+
diff --git a/test/data/app/view/form/fetch_call.php b/test/data/app/view/form/fetch_call.php
new file mode 100644
index 000000000..2aa442f54
--- /dev/null
+++ b/test/data/app/view/form/fetch_call.php
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+ Fetch JSON data
+
+
+
+ JSON data
+
+
+
+
+
No data here
+
+
+
+
+
diff --git a/test/data/app/view/form/file.php b/test/data/app/view/form/file.php
index 47e037f07..13b03bca0 100755
--- a/test/data/app/view/form/file.php
+++ b/test/data/app/view/form/file.php
@@ -5,5 +5,9 @@
+