[
  {
    "path": ".dockerignore",
    "content": "*/node_modules\n*.log\n"
  },
  {
    "path": ".editorconfig",
    "content": "root=true\n\n[*]\ncharset=utf-8\nend_of_line=lf\ninsert_final_newline=true\nindent_style=space\nindent_size=2\n\n[Makefile]\nindent_style = tab\n\n[*.feature]\nindent_style=space\nindent_size=4\n"
  },
  {
    "path": ".gitignore",
    "content": "#build files\ndist\n\n# dependencies\nnode_modules\n\n#tests\nselenium-debug.log\nreports\nscreenshots\ntestium\ntmp-*\nnpm-debug.log\n.idea\ndownloads/*\n!functional-tests/downloads/.gitkeep\n!functional-tests/downloads/example.xlsx\ndocker-compose.override.yml\n!downloads/.gitkeep\n!functional-tests/reports/.gitkeep\n!functional-tests/reports/report/.gitkeep\n!functional-tests/reports/report/features/.gitkeep\n!functional-tests/performance/.gitkeep\n!example/reports/.gitkeep\n!reports/.gitkeep\n.DS_Store\nfunctional-tests/package-lock.json\n\nwebsite/yarn.lock\nwebsite/node_modules\nwebsite/i18n/*\n\nlocal.log\nbrowserstack.err"
  },
  {
    "path": ".npmignore",
    "content": "website\nfunctional-tests\ndocs"
  },
  {
    "path": ".prettierrc",
    "content": "{\n    \"useTabs\": false,\n    \"printWidth\": 120,\n    \"tabWidth\": 2,\n    \"singleQuote\": true,\n    \"trailingComma\": \"es5\",\n    \"bracketSpacing\": true\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n- \"lts/*\"\naddons:\n  chrome: stable\nscript:\n- npm run test-ci\n- npm run lint\n"
  },
  {
    "path": "CHANGELOG.MD",
    "content": "#### v3.0.0\n\n- added support for Browserstack\n- updated external libraries\n- locked selenium-standalone-server to `3.14.0` to prevent bugs caused due to updated external libraries (we'll update it manually)\n- coverted Kakunin from Javascript to Typescript\n- added possibility to set priority of hooks <span style=\"color:red\">Breaking change! Take a look to the MIGRATION-3.0.0.MD</span>\n\n#### v2.6.0\n\n- added possibility to control `headless` by CLI by a command `npm run kakunin -- --headless`\n- added a possibility to visit URL w query params\n- added support for Internet Explorer\n\n#### v2.5.0\n\n- added prepublish script to run tests before publish on NPM\n- improved logging errors in the console\n- added docusaurus documentation\n- added possibility to test REST API\n\n#### v2.4.0\n\n- `When I pause` step has been deleted as the `browser.pause()` method is not supported since Node 8.x.x\n- added `how to debug` section to the documentation\n- added example how to configure docker for Kakunin projects\n- configured Travis CI - unit and functional tests\n- added support for Safari and Firefox browsers (take a look at the `cross-browser` section in the documentation)\n- added parallel functionality (take a look at the `parallel` section in the documentation)\n- configured prettier and eslint on `git commit` action\n- added a possibility to use `When I store` and `There is element` steps on `input`/`textarea` fields\n- added `faker` generator (generate random names, cities etc.)\n\n##### v2.3.0\n\n- added a new step: `success if email not found`\n- updated `emails section` in the documentation\n- added a possibility to answer prompts by a bash command in the `init process`\n- fixed `file.js` step and added functional tests covering `compare xlsx with stored data`\n- updated dependencies\n\n##### v2.2.0\n\n- added migration rules to version `v2.2.0`\n- fixed `wait for url change` error\n- improved CLI scripts and added tests\n- improved `When I click step` - added an extra wait until the element is clickable\n- fixed the cache problem in the `local storage` (wait until the cache is cleared)\n- improved how the matchers errors are displayed\n- changed Mocca into Jest\n- changed Chai for Jest syntax\n- moved `maxEmailRepeats` to the configuration\n- updated Mailtrap adapter due to changed API (take a look at the `MIGRATION-2.2.0.MD`)\n- updated dependencies\n\n##### v2.1.0\n\n- multiple code refactors\n- improved url comparing\n- fixed bug: missing \"reports/report/features\" catalogs required to execute tests\n- added functionality which deletes all report files before a test run\n- added new matcher - `f:currentDate:YYYY-MM-DD` to generate a current date\n- added a possibility to test performance with browserMob (save .har files) and compare TTFB timing values\n- improvements for clicking element\n- every element step waits for visibilityOf element (waiting before step is no longer required in common cases)\n- added wait method to helpers, also is exported outside of kakunin\n- added deprecated warning for is Present steps\n- added matcher for currentDate\n- code refactor for kakunin.conf.js\n- replaced generator step with real generator supporting multiple params\n- code cleanup (unused imports etc.),\n- documentation update and test update (added useful undocumented and untested steps, removal of unused steps)\n\n##### v2.0.0\n\n- updated documentation\n- added more functional tests\n- added support for Windows\n- added support for `relative` and `absolute` urls in Page Objects\n- added `BaseDictionary` functionality\n- added new step (support drag and drop) `I drag \"elementName\" element and drop over \"dropOnElementName\" element`\n- fixed reports\n- fixed step `I wait for the \"elementName\" element to disappear`\n- updated libs (e.g. cucumber js)\n- `isExternal` is no longer required in Page Objects (Angular)\n- locators are no longer supported in Page Objects\n- export `module.exports` has been changed in Page Objects\n- removed `| element | value |` headers from first row in a steps\n- `.gitkeep` is automatically created in reports catalog\n- `RELOAD_FIXTURES_URL` has been moved to advanced configuration\n- step `the \"arrayElementName\" element is visible` can be used now for an array element\n\n##### v1.0.0\n\n- updated documentation\n- added license\n- added example\n\n##### v0.16.4\n\n- updated documentation and readme\n\n##### v0.16.3\n\n- changed `There are \"equal 4\" following elements for element \"rows\":` error message to be more descriptive\n- added express app to handle form submit tests\n- added tests form html default field types and tabular content validation\n\n##### v0.16.2\n\n- added new step `I visit the \"pageName\" page with parameters:` which replaces wildcards with a values given in the table\n- fixed step `I wait for \"condition\" of the \"element\" element`, currently timeout is set properly to `elementsVisibilityTimeout` key which is placed in kakunin.config.js\n- improved step `I wait for \"condition\" of the \"element\" element`, currently singleElement and arrayElements can be checked\n- change step implementation: `I click the \"keyName\" key` to `I press the \"keyName\" key`\n\n##### v0.16.1\n\n- added changelog\n- added directory for mailing service adapters [`emails`] and connect it to modules loading system\n- fixed a bug where exported mailing service and the one used internally where a different instances\n"
  },
  {
    "path": "CONTRIBUTING.MD",
    "content": "# Contributing to Kakunin\n\n\nThis section will guide you through the contribution process.\n\n### Step 1: Fork\n\nFork the project [on GitHub](https://github.com/TheSoftwareHouse/Kakunin) and clone your fork\nlocally.\n\n```bash\ngit clone git@github.com:TheSoftwareHouse/Kakunin.git\ncd Kakunin\ngit remote add upstream https://github.com/TheSoftwareHouse/Kakunin.git\n```\n\n#### Which branch?\n\nFor developing new features and bug fixes, the `master` branch should be pulled\nand built upon.\n\n\n### Step 2: Branch\n\nCreate a branch and start hacking:\n\n```bash\ngit checkout -b my-branch -t origin/master\n```\n\n### Step 3: Commit\n\nMake sure git knows your name and email address:\n\n```bash\ngit config --global user.name \"Jan Kowalski\"\ngit config --global user.email \"jan@kowalski.com\"\n```\n\nAdd and commit:\n\n```bash\n$ git add my/changed/files\n$ git commit\n```\n\n### Commit message guidelines\n\nThe commit message should describe what changed and why. We don't put any \nconstraints on message format although it should clearly describe the change.\n\n4. If your patch fixes an open issue, you can add a reference to it at the end\nof the log. Use the `Fixes:` prefix and the full issue URL. For other references\nuse `Refs:`.\n\n   Examples:\n   - `Fixes: https://github.com/TheSoftwareHouse/Kakunin/issues/1337`\n   - `Refs: http://eslint.org/docs/rules/space-in-parens.html`\n   - `Refs: https://github.com/TheSoftwareHouse/Kakunin/pull/1234`\n\n\n### Step 4: Rebase\n\nUse `git rebase` (not `git merge`) to synchronize your work with the main\nrepository.\n\n```bash\n$ git fetch upstream\n$ git rebase upstream/master\n```\n\n### Step 5: Test\n\nBug fixes and features should come with tests. Looking at other tests to \nsee how they should be structured can help. \n\nTo run the tests just run the default command:\n\n```bash\nnpm test\n```\n\nMake sure the linter does not report any issues and that all tests pass. Please\ndo not submit patches that fail either check.\n\n\n### Step 6: Push\n\n```bash\ngit push origin my-branch\n```\n\nPull requests are usually reviewed within a few days.\n\n### Step 7: Discuss and update\n\nYou will probably get feedback or requests for changes to your Pull Request.\nThis is a big part of the submission process so don't be discouraged!\n\nTo make changes to an existing Pull Request, make the changes to your branch.\nWhen you push that branch to your fork, GitHub will automatically update the\nPull Request.\n\n\nFeel free to post a comment in the Pull Request to ping reviewers if you are\nawaiting an answer on something. \n\n### Step 8: Landing\n\nIn order to land, a Pull Request needs to be reviewed and approved by\nat least one Kakunin Collaborator and pass all test.\nAfter that, as long as there are no objections from a Collaborator, \nthe Pull Request can be merged.\n\nAfter you push new changes to your branch, you need to get\napproval for these new changes again, even if GitHub shows \"Approved\"\nbecause the reviewers have hit the buttons before.\n\n## Developer's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n* (a) The contribution was created in whole or in part by me and I\n  have the right to submit it under the open source license\n  indicated in the file; or\n\n* (b) The contribution is based upon previous work that, to the best\n  of my knowledge, is covered under an appropriate open source\n  license and I have the right under that license to submit that\n  work with modifications, whether created in whole or in part\n  by me, under the same open source license (unless I am\n  permitted to submit under a different license), as indicated\n  in the file; or\n\n* (c) The contribution was provided directly to me by some other\n  person who certified (a), (b) or (c) and I have not modified\n  it.\n\n* (d) I understand and agree that this project and the contribution\n  are public and that a record of the contribution (including all\n  personal information I submit with it, including my sign-off) is\n  maintained indefinitely and may be redistributed consistent with\n  this project or the open source license(s) involved.\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM node:8.11.4\n\nWORKDIR /app/website\n\nEXPOSE 3000 35729\nCOPY kakunin/docs /app/docs\nCOPY ./website /app/website\nRUN yarn install\n\nCMD [\"yarn\", \"start\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 The Software House\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "MIGRATION-2.0.0.MD",
    "content": "# Kakunin - automated testing framework\n#### Migration to 2.0.0 version\n\nWhat needs to be done:\n1. Remove all locators from Page Objects\n```javascript\nthis.exampleLocator = by.css('.unique-class');\n```\n\nneeds to be changed to:\n\n```javascript\nthis.exampleLocator = $('.unique-class');\n```\n\n2. Remove headers `| element | value |` from all steps\n```gherkin\nAnd there are \"equal 1\" following elements for element \"rows\":\n   | element   | value  |\n   | firstName | t:John |\n   | lastName  | t:Doe  |\n```\n\nneeds to be changed to:\n\n```gherkin\nAnd there are \"equal 1\" following elements for element \"rows\":\n   | firstName | t:John |\n   | lastName  | t:Doe  |\n```\n\n3. Delete `isExternal` from all Page Objects, if you are using Angular application\n```javascript\nclass ExamplePage extends BasePage {\n  constructor() {\n    super();\n    this.isExternal = true;\n\n    this.url = '/';\n\n    this.selector = $('.some-class');\n  }\n```\n\nneeds to be changed to:\n\n```javascript\nclass ExamplePage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/';\n\n    this.selector = $('.some-class');\n  }\n```\n\n4. Change `exports` in Page Objects:\nThe last line in each of the page objects\n```javascript\nmodule.exports = new ExamplePage();\n```\n\nneeds to be changed to:\n\n```javascript\nmodule.exports = ExamplePage;\n```\n\n\n5. Change `dictionaries`, example:\n```javascript\nconst { dictionaries } = require('kakunin');\n\nclass TestDictionary {\n  constructor() {\n    this.values = {\n      'test-name': 'Janek',\n      'test-value': 'lux'\n    };\n\n    this.name = 'test-dictionary';\n  }\n\n  isSatisfiedBy(name) {\n    return this.name === name;\n  }\n\n  getMappedValue(key) {\n    return this.values[key];\n  }\n}\n\ndictionaries.addDictionary(new TestDictionary());\n```\n\nneeds to be changed to:\n\n```javascript\nconst { dictionaries } = require('kakunin');\nconst { BaseDictionary } = require('kakunin');\n\nclass TestDictionary extends BaseDictionary {\n  constructor() {\n    super('test-dictionary', {\n      'test-name': 'Janek',\n      'test-value': 'lux'\n    });\n  }\n}\n\ndictionaries.addDictionary(new TestDictionary());\n```\n"
  },
  {
    "path": "MIGRATION-2.2.0.MD",
    "content": "# Kakunin - automated testing framework\n#### Migration to 2.2.0 version\n\nWhat needs to be done:\n1. If you are using MailTrap client to tests emails.\nOpen `kakunin.conf.js` file and edit it:\n```javascript\n  email: {\n    type: 'mailtrap',\n    config: {\n      apiKey: '',\n      inboxId: '',\n      url: 'https://mailtrap.io/api/v1',\n    },\n  },\n```\n\nneeds to be changed to:\n\n```javascript\n  email: {\n    type: 'mailtrap',\n    config: {\n      apiKey: '',\n      inboxId: '',\n      url: 'https://mailtrap.io',\n    },\n  },\n```\n\nThis change is required due to API changes in MailTrap.\nMore details available under the link: https://mailtrap.io/blog/2018-06-06-mailtraps-upcoming-api-changes\n\nPlease note that, that the steps in scenarios do not require any changes!\nYou can still use `html_body` to check the email content.\n\nThis is a breaking change for users using MailTrap in tests but we did not want to change version to \"3.0.0\".\nJust \"minor\" version has been increased by one.\n\n2. Remove node_modules\n3. Update protractor to newest version - `npm install protractor@latest --save`\n4. If you have some custom matchers, make sure to make them return rejected promise on fail. This is done to improve error readability.\n"
  },
  {
    "path": "MIGRATION-3.0.0.MD",
    "content": "# Kakunin - automated testing framework\n#### Migration to 3.0.0 version\n\nWhat needs to be done:\n1. Change Hooks\n\nIn the version before 3.0.0 we had a single file located in the `./hook` directory.\n\nExample of `hook.js`:\n\n```javascript\nconst { Before, After } = require('kakunin');\n\nBefore(() => {\n  console.log('If you can see this in console then hook is working properly.');\n});\n\nAfter(() => {\n  console.log('Console log after the scenario');\n});\n```\n\nCurrently, the interface to set priorities has been added. So we can control if the hook `FirstExample` will be executed before `SecondExample`.\n\n\nExample of `first-example.hook.js`:\n\n```javascript\nconst { hookHandlers, Before } = require('kakunin');\n\nclass FirstExampleHook {\n  initializeHook() {\n    Before(() => {\n      console.log('First example hook');\n    });\n  }\n\n  getPriority() {\n    return 990;\n  }\n}\n\nhookHandlers.addHook(new FirstExampleHook());\n\n```\n\n"
  },
  {
    "path": "ROADMAP.MD",
    "content": "## Roadmap\n\n### v2.1.0\n\n* Allow to test REST endpoints against expected JSON Schema\n\n### v2.0.0\n\n* full support for Windows OS,\n\n* we are going to drop the need for strict first row in gherkin tables. For example, instead of:\n  ``` gherkin\n    Given there are \"at least 5\" following elements for element \"items\":\n    | element    | value       |\n    | viewButton | f:isVisible | \n  ```\n  \n  you will be able to write it like this:\n  \n  ``` gherkin\n    Given there are \"at least 5\" following elements for element \"items\":\n    | viewButton | f:isVisible | \n  ```\n  \n  this change will be introduced to all tables related steps.  \n\n* we are going to drop the need for defining `locators` instead of `selectors` for some table steps. For example:\n\n  ``` gherkin\n    Given there are \"at least 5\" following elements for element \"items\":\n    | element    | value       |\n    | viewButton | f:isVisible | \n  ```\n    \n  Currently the `viewButton` must be defined as `this.viewButtonLocator = by.css('.viewButton')`. In case you wish to click on such locator, you have to create a \n  selector for it - `this.viewButton = element(this.viewButtonLocator)`. \n  \n  We are aware of code duplication issue here and after investigation this will be fixed in upcoming major version.\n  \n  From `v2.0.0` you'll be able to use `this.viewButton = element(by.css('.viewButton'))` (and even the `$()` shortcut) in every step.\n"
  },
  {
    "path": "build.sh",
    "content": "#!/bin/sh\ngit subtree push --prefix website/build/Kakunin origin gh-pages\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: \"3\"\n\nservices:\n  docusaurus:\n    build: .\n    ports:\n      - 3000:3000\n      - 35729:35729\n    volumes:\n      - ./docs:/app/docs\n      - ./website/blog:/app/website/blog\n      - ./website/core:/app/website/core\n      - ./website/i18n:/app/website/i18n\n      - ./website/pages:/app/website/pages\n      - ./website/static:/app/website/static\n      - ./website/sidebars.json:/app/website/sidebars.json\n      - ./website/siteConfig.js:/app/website/siteConfig.js\n    working_dir: /app/website\n"
  },
  {
    "path": "docs/browserstack.md",
    "content": "---\nid: browserstack\ntitle: Browserstack integration\n---\n\n## Browserstack project configuration\n\n1. Create a new account in Browserstack: https://www.browserstack.com/\n2. Login and visit the website https://www.browserstack.com/accounts/settings\n3. Scroll down to the `Automation` section and copy:\n- `Username`\n- `Access Key`\n\n4. Add a new `browserstack` section to the `kakunin.conf.js` file in the repository.\nThis is an example of a configuration for IE8 on Windows 7.\n\n```javascript \n  browserstack: {\n    seleniumAddress: 'http://hub-cloud.browserstack.com/wd/hub',\n    defaultPort: 45691,\n    capabilities: {\n      'browserstack.user': 'example-user',\n      'browserstack.key': 'example-key',\n      'browserstack.local': true,\n      nativeEvents: true,\n      'browserstack.ie.driver': '3.14.0',\n      'browserstack.selenium_version': '3.14.0',\n      browserName: 'IE',\n      browser_version: '8.0',\n    }\n  },\n```\n\n5. Set `'browserstack.user'` to the `Username` value that you copied from the `Automation` section\n6. Set `'browserstack.key'` to the `Access Key` value that you copied from the `Automation` section\n\n7. Visit the link https://www.browserstack.com/automate/capabilities if you want to find more capabilities for your project!.\n\n## Run tests in Browserstack\n\nRuns the application with the capabilities set in `kakunin.conf.js` file through the command line:\n- `npm run kakunin -- --browserstack` \n\n<span style=\"color:red\">Keep in mind that all capabilities that you set via CLI will be ignored!</span>\n\nFor example, `npm run kakunin -- --safari --browserstack` will ignore the `safari` part. \nOnly `--browserstack` matters in case of running tests in Browserstack.\n\n\n## Example kakunin.conf.js configuration file\n\nThis is an example configuration for Internet Explorer 8 on Windows 7. \n\n```javascript \nmodule.exports = {\n  browserWidth: 1600,\n  browserHeight: 900,\n  timeout: 60,\n  elementsVisibilityTimeout: 5,\n  waitForPageTimeout: 5,\n  downloadTimeout: 30,\n  reports: '/reports',\n  downloads: '/downloads',\n  data: '/data',\n  features: ['/features'],\n  pages: ['/pages'],\n  matchers: ['/matchers'],\n  generators: ['/generators'],\n  form_handlers: ['/form_handlers'],\n  step_definitions: ['/step_definitions'],\n  comparators: ['/comparators'],\n  dictionaries: ['/dictionaries'],\n  transformers: ['/transformers'],\n  regexes: ['/regexes'],\n  hooks: ['/hooks'],\n  clearEmailInboxBeforeTests: false,\n  clearCookiesAfterScenario: true,\n  clearLocalStorageAfterScenario: true,\n  email: null,\n  headless: true,\n  noGpu: true,\n  type: 'otherWeb',\n  baseUrl: 'http://localhost:8080',\n  apiUrl: 'http://localhost:8080/',\n  browserstack: {\n    seleniumAddress: 'http://hub-cloud.browserstack.com/wd/hub',\n    defaultPort: 45691,\n    capabilities: {\n      'browserstack.user': 'example-user',\n      'browserstack.key': 'example-key',\n      'browserstack.local': true,\n      nativeEvents: true,\n      'browserstack.ie.driver': '3.14.0',\n      'browserstack.selenium_version': '3.14.0',\n      browserName: 'IE',\n      browser_version: '8.0',\n    }\n  },\n};\n```"
  },
  {
    "path": "docs/configuration.md",
    "content": "---\nid: configuration\ntitle: Configuration\n---\n\n## Kakunin config\n\n```\nmodule.exports = {\n    \"browserWidth\": 1600,\n    \"browserHeight\": 900,\n    \"timeout\": 60,\n    \"maxEmailRepeats\": 5,\n    \"intervalEmail\": 5,\n    \"elementsVisibilityTimeout\": 5,\n    \"waitForPageTimeout\": 5,\n    \"downloadTimeout\": 30,\n    \"reports\": \"/reports\",\n    \"downloads\": \"/downloads\",\n    \"data\": \"/data\",\n    \"features\": [\n        \"/features\"\n    ],\n    \"pages\": [\n        \"/pages\"\n    ],\n    \"matchers\": [\n        \"/matchers\"\n    ],\n    \"generators\": [\n        \"/generators\"\n    ],\n    \"form_handlers\": [\n        \"/form_handlers\"\n    ],\n    \"step_definitions\": [\n        \"/step_definitions\"\n    ],\n    \"comparators\": [\n        \"/comparators\"\n    ],\n    \"dictionaries\": [\n        \"/dictionaries\"\n    ],\n    \"transformers\": [\n        \"/transformers\"\n    ],\n    \"regexes\": [\n        \"/regexes\"\n    ],\n    \"hooks\": [\n        \"/hooks\"\n    ],\n    \"clearEmailInboxBeforeTests\": false,\n    \"clearCookiesAfterScenario\": true,\n    \"clearLocalStorageAfterScenario\": true,\n    \"email\": null,\n    \"headless\": false,\n    \"noGpu\": false,\n    \"type\": \"otherWeb\",\n    \"baseUrl\": \"http://localhost:8080\",\n    \"accounts\": {\n        \"someAccount\": {\n            \"accounts\": [\n                {\n                    \"email\": \"\",\n                    \"password\": \"\"\n                }\n            ]\n        }\n    }\n}\n\n```\n\n## Configuration options\n\n`browserWidth` - width of browser window `default: 1600`\n\n`browserheight` - height of browser window `default: 900`\n\n`timeout` - global timeout for a single step execution in seconds `default: 60`\n\n`maxEmailRepeats` - maximum email repeats to catch email used in the email step\n\n`intervalEmail` - interval for email checking step `default: 5` in seconds\n\n`elementsVisibilityTimeout` - maximum wait timeout for element visibility `default: 5` seconds\n\n`waitForPageTimeout` - maximum wait timeout for page visibility `default: 5` seconds\n\n`downloadTimeout` - maximum wait timeout for file to be downloaded `default: 30` seconds\n\n`emails` - array of paths to store emails related custom code\n\n`reports` - path to store reports\n\n`downloads` - path to store downloaded files\n\n`data` - path to store test related files (for example files to be downloaded)\n\n`feature` - array of paths to store features\n\n`pages` - array of paths to store page objects\n\n`matchers` - array of paths to store custom matchers\n\n`generators` - array of paths to store custom generators\n\n`form_handlers` - array of paths to store custom form handlers\n\n`step_definitions` - array of paths to store custom steps\n\n`comparators` - array of paths to store custom comparators\n\n`dictionaries` - array of paths to store custom dictionaries\n\n`transformers` - array of paths to store custom transformers\n\n`regexes` - array of paths to store custom regexes\n\n`hooks` - array of paths to store custom hooks\n\n`clearEmailInboxBeforeTests` - flag to active clearing email inbox before tests are executed `default: false | true for apps with email checking functionality activated `\n\n`clearCookiesAfterScenario` - flag to activate clearing cookies after every scenario `default: true`\n\n`clearLocalStorageAfterScenario` - flag to activate clearing local storage after every scenario `default: true`\n\n`email` - email configuration `default: null`\n\nfor mailtrap email checking system:\n\n```javascript \n\"type\": \"mailtrap\",\n\"config\": {\n    \"apiKey\": \"your-mailtrap-api-key\",\n    \"inboxId\": \"your-mailtrap-inbox\",\n    \"url\": \"https://mailtrap.io/api/v1\"\n}\n```\n\nfor custom email checking system only type is required:\n\n``` \n\"type\": \"custom-type\"\n```\n\n`headless` - flag to activate chrome headless browser `default: false`. Keep in mind that CLI command `-- --headless=false/true` has higher priority than the config file.\n\n`noGpu` - flag to activate cpu only mode `default: false`\n\n`type` - type of application either `ng1 | ng2 | otherWeb`\n\n`baseUrl` - url of tested application\n\n`accounts` - object to store accounts information. This is bound to `userProvider` and allows to use advanced email checking options like recipient checking.\n\n```javascript \n\"someAccount\": {\n    \"accounts\": [\n        {\n            \"email\": \"\",\n            \"password\": \"\"\n        }\n    ]\n}\n```\n\n## Environment variables\n\nKakunin uses a single `.env` file to load ENV variables. By default there is only one:\n\n`FIXTURES_RELOAD_HOST` - allows you to specify host for fixtures reloading. This allows you to use `@reloadFixtures` tag on scenarios that should restore database to starting state, before the test is running\n"
  },
  {
    "path": "docs/cross-browser.md",
    "content": "---\nid: cross-browser\ntitle: Cross-browser testing\n---\n\n## To run tests with specified browser\nThere is a possibility to run Kakunin in various browsers:\n\n- Google Chrome (by default) `npm run kakunin` or `npm run kakunin -- --chrome`\n- Firefox `npm run kakunin -- --firefox`\n- Safari `npm run kakunin -- --safari`\n- Internet Explorer `npm run kakunin -- --ie` <span style=\"color:blue\">(supported versions IE8, IE9, IE10, IE11)</span>\n\n## To run tests in different browsers at once\nThere is a possibility to run more than one instance of WebDriver by giving an extra parameter to a command line:\n\n- `npm run kakunin --chrome --safari`\n\nCurrently, there is a problem with running more than one instance of Firefox!\n\n## Safari\n### Run tests\n1. Open Safari's preferences\n2. Enable \"Show Develop menu in menu bar\"\n3. Open \"Develop\" tab\n4. Enable \"Allow Remote Automation\"\n\n## Internet Explorer\n### Configure the browser\n1. Open Internet options and set:\n- IE browser zoom level to 100 procent\n- IE Security level: keep all of the tabs either checked / unchecked (Itnernet, Local internet, Trusted sites, Restricted sites)\n\n### Troubleshooting\nSafari version 12.0:\n- drag & drop actions in Kakunin impossible (more details https://github.com/angular/protractor/issues/1526)\n"
  },
  {
    "path": "docs/docker.md",
    "content": "---\nid: docker\ntitle: Docker\n---\n\n# Docker for Kakunin tests\n\nThis section explains how to run kakunin tests inside docker, below examples of Dockerfile\nand docker-compose.yml files let you build your first docker image and run tests.\n\n## Dockerfile:\n\nThis file is responsible for building the whole environment for our e2e tests.\nIt will allow you to run tests on local and CI environments, \nby configuring and copying the whole project inside the container.\nJust simply place it inside your e2e project root.\n\nBelow an example of Dockerfile\n\n### Example of Dockerfile:\n```bash\n# Downloading selenium image and setting privileges\nFROM selenium/standalone-chrome:3.14.0\nUSER root\n# Setting test directory\nWORKDIR /app\n# Install openjdk-8-jdk-headless\nRUN apt-get update -qqy \\\n  && apt-get -qqy --no-install-recommends install \\\n    xvfb \\\n    openjdk-8-jdk-headless \\\n    curl \\\n    make \\\n  && rm -rf /var/lib/apt/lists/* /var/cache/apt/*\n# Installing node 8 globally and setting paths\nRUN set -x \\\n    && curl -sL https://deb.nodesource.com/setup_8.x | bash - \\\n    && apt-get install -y \\\n        nodejs \\\n    && npm install -g npm@latest\nRUN PATH=/usr/bin/node:$PATH\n# Copy tests directory with ignored files from .dockerignore\nCOPY --chown=seluser:seluser . .\n# Removing node_modules in case of existence or lack of .dockerignore and installing from package.json\nRUN rm -rf ./node_modules \\\n    && npm install\n# Setting Xvfb\nRUN export DISPLAY=:99.0\nUSER seluser\n```\n\n##docker-compose.yml\n\nCompose is a tool for defining and running multi-container Docker applications, which we use\nfor running our tests.\n\nRunning command: ``docker-compose up -d`` will start Dockerfile script, as a result, it builds the container.\n \nRunning command: ``docker-compose build `` or ``docker-compose up --build`` will \nrebuild container, if there were made any changes.\n \nRunning command: ``docker-compose run --rm e2e`` will start running tests inside the container\n\n\nComposition below allows you to run e2e tests inside the container and configure it locally or\nin CI environments.\n\n\n### Example of docker-compose.yml:\n```bash\ne2e:\n      build: .\n      working_dir: /app\n      command: sh -c \"Xvfb -ac :99 -screen 0 1280x1024x16 & npm run kakunin\"\n```\n\n### How to run step by step\n1. Install docker (e.g Docker for Mac),\n2. Create Dockerfile and docker-compose.yml in the root of your e2e project,\n3. Run in command line `docker-compose up -d ` which will start docker and build image\n if it's not build\n4. Run in command line `docker-compose run --rm e2e` to run your tests\n\n"
  },
  {
    "path": "docs/extending.md",
    "content": "---\nid: extending\ntitle: Extending Kakunin\n---\n\nKakunin allows you to easily add a custom code in order to extend it's functionality.\n\n## Internal services\n\n### Regex builder\n\nRegex builder is a special builder for creating `RegExp` objects based on regexp name. Internally it has access to not only to all built-in \nregular expression files, but also custom ones specified by user. \n\n```javascript\nconst { regexBuilder } = require('kakunin');\n\nconst myRegex = regexBuilder.buildRegex('r:number');\n\n//myRegex will contain RegExp object that matches regular expression under the name \"number\" in regexes file.\n```\n\n### Variable store\n\nVariable store allows you to store and read some values to be used during given scenario.\n\n```javascript\nconst { variableStore } = require('kakunin');\n\nvariableStore.storeVariable('some-name', 'some-value');\n\nconst myValue = variableStore.getVariableValue('some-name'); //contains 'some-value'\n```\n\n### User provider\n\nKakunin comes with functionality that allows you to easily load credentials for a given account type - `UserProvider`.\n\nIn `kakunin.conf.js` you can find a section `accounts`.\n\nThe structure it has is very simple: \n\n```json \n\"accounts\": {\n    \"someAccount\": {\n        \"accounts\": [\n            {\n                \"email\": \"\",\n                \"password\": \"\"\n            }\n        ]\n    }\n}\n```\n\n`someAccount` - the name of accounts group\n\n`accounts` - an array of account credentials (in order to be able to check if a `currentUser` got an email, this has to have an `email` key, otherwise account can have any kind of\nproperties)\n\nUse provider is accessible inside any kind of a step by calling `this.userProvider`. It comes with a single method:\n\n`this.userProvider.getUser(groupName)` - returns an account credentials for a given user group.\n\nIt is a good practice to save a current user in `this.currentUser` variable for a email checking service.\n\n## Adding custom code\n\n### Custom step\n\nIn order to add a custom step, you have to create inside of a directory specified as `step_definitions` in kakunin configuration file `default: /step_definitions`.\n\nWe're using `cucumber-js 4.X` so in order to add custom step you have to use `defineSupportCode` method like this:\n\n```javascript\n  const { defineSupportCode } = require('kakunin');\n  \n  defineSupportCode(({ When }) => {\n    When(/^I use kakunin$/, function() {\n      expect(true).to.equal(true);\n    });\n  });\n```\n\n### Page objects\n\nKakunin comes with some built-in page objects, that should be used as a base for your page objects.\n\nIn order to create a custom one, create a file inside the `pages` directory and extend the `BasePage` from kakunin package.\n\n```javascript\nconst { BasePage } = require('kakunin');\n\nclass MyPageObject extends BasePage {\n  constructor() {\n    this.myElement = element(by.css('.some-elemnt'));\n  }\n}\n\nmodule.exports = MyPageObject;\n```\n\n### Matchers\n\nMatchers are used to compare if given value is matching our expectation. For example if a value in table is a number.\n\nYou can add your own matcher as below:\n\n```javascript\nconst { matchers } = require('kakunin');\n\nclass MyMatcher {\n  isSatisfiedBy(prefix, name) {\n    return prefix === 'm:' && name === 'pending';\n  }\n \n  match(protractorElement, matcherName) {\n    return protractorElement.getText().then((value) => {\n      if (value === 'pending') {\n        return true;\n      }\n      \n      return Promise.reject(`Matcher \"MyMatcher\" could not match value on element \"${protractorElement.locator()}\". Expected: \"pending\", given: \"${value}\"`);\n    }); \n  }\n}\n\nmatchers.addMatcher(new MyMatcher());\n```\n\n### Dictionaries\n\nDictionaries allows you to present complicated values in much more readable way. For example if an element must be\nin a form of IRI `/some-resource/123-123-123-23` and you wish to use `pending-resource` as it's alias.\n\nYou can add your own dictionary:\n\n```javascript\nconst { dictionaries } = require('kakunin');\nconst { BaseDictionary } = require('kakunin');\n\nclass TestDictionary extends BaseDictionary {\n  constructor() {\n    super('name-of-dictionary', {\n      'pending-resource': '/some-resource/123-123-123-23',\n      'test-value': 'some other value'\n    });\n  }\n}\n\ndictionaries.addDictionary(new TestDictionary());\n```\n\n### Generators\n\nGenerators allows you to create random values\n\nYou can add your own generator:\n\n```javascript\nconst { generators } = require('kakunin');\n\nclass MyGeneerator{\n  isSatisfiedBy(name) {\n    return name === 'my-generator';\n  }\n\n  generate(params) {\n    return Promise.resolve('some-random-value');\n  }\n}\n\ngenerators.addGenerator(new MyGeneerator());\n```\n\n### Comparators\n\nComparators allows you to check if a set of values has an expected order\n\nYou can add your own comparators:\n\n```javascript\nconst { comparators } = require('kakunin');\n\nclass MyComparator {\n  isSatisfiedBy(values) {\n    for(let i=0; i<values.length; i++) {\n      if (values[i] !== 'foo' && values[i] !== 'bar') {\n        return false;\n      }\n    }\n\n    return true;\n  }\n  \n  compare(values, order) {\n    for (let i = 1; i < values.length; i++) {\n      const previousValue = values[i - 1];\n      const currentValue = values[i];\n\n      if (previousValue === currentValue) {\n        return Promise.reject('Wrong order');\n      }\n    }\n\n    return Promise.resolve('Foo bar!');\n  }\n};\n\ncomparators.addComparator(new MyComparator());\n```\n\n### Form handlers\n\nForm handlers allows you to fill the form inputs and check value of filled fields\n\nYou can add your own handlers:\n\n```javascript\nconst { handlers } = require('kakunin');\n\nconst MyHandler {\n  constructor() {\n    this.registerFieldType = false;\n    this.fieldType = 'default';\n  }\n\n  isSatisfiedBy(element, elementName) {\n    return Promise.resolve(elementName === 'someElementName');\n  }\n \n  handleFill(page, elementName, desiredValue) {\n    return page[elementName].isDisplayed()\n      .then(function () {\n        return page[elementName].clear().then(function () {\n          return page[elementName].sendKeys(desiredValue);\n        });\n      }\n    );\n  }\n\n  handleCheck(page, elementName, desiredValue) {\n    return page[elementName].isDisplayed()\n      .then(function () {\n        return page[elementName].getAttribute('value').then(function (value) {\n          if (value === desiredValue) {\n            return Promise.resolve();\n          }\n\n          return Promise.reject(`Expected ${desiredValue} got ${value} for text input element ${elementName}`);\n        });\n      }\n    );\n  }\n};\n\nhandlers.addHandler(new MyHandler());\n```\n\n### Transformers\n\nTransformers can be used in steps `When I fill the \"form\" form with:` and `And the \"joinOurStoreForm\" form is filled with:`.\n\nExisting transformers:\n- generators (prefix: `g:`)\n- dictionaries (prefix: `d:`)\n- variableStore (prefix: `v:`)\nTransformers can be used in mentioned steps by using specific 'prefix', parameters are sent after `:` sign.\nExample:\n`g:generatorName:param:param`\n\nYou can add your own handlers:\n```javascript\nconst { transformers } = require('kakunin');\n\nclass MyTransformer {\n\n  isSatisfiedBy(prefix) {\n    return 'yourPrefix:' === prefix;\n  }\n\n  transform(value) {\n    //code\n  }\n}\ntransformers.addTransformer(new MyTransformer());\n```\n\n### Email checking service\n\nYou can easily check emails with Kakunin. By default we give you MailTrap client implementation, but you can easily add your own client. \n\n```javascript\nconst { emailService } = require('kakunin');\n\nclass MyEmailService {\n  //you have access to full kakunin config\n  isSatisfiedBy(config) {\n    return config.email.type === 'my-custom-email-service';\n  }\n  \n  //method used to clear emails before tests\n  clearInbox() {\n    ...\n  }\n  \n  //method used to get emails - this method should return emails in format described below\n  getEmails() {\n    ...\n  }\n  \n  //method used to retrive atachments for given email - should return attachments in format described below\n  getAttachments(email) {\n    ...\n  }\n  \n  //method used to mark given email as read\n  markAsRead(email) {\n    ...\n  }\n}\n\nemailService.addAdapter(new MyEmailService());\n```\n\nEmails should be returned as an array of objects with given schema:\n```javascript \n  [\n    {\n      \"subject\": \"SMTP e-mail test\",\n      \"sent_at\": \"2013-08-25T19:32:07.567+03:00\",\n      \"from_email\": \"me@railsware.com\",\n      \"from_name\": \"Private Person\",\n      \"to_email\": \"test@railsware.com\",\n      \"to_name\": \"A Test User\",\n      \"html_body\": \"\",\n      \"text_body\": \"This is a test e-mail message.\\r\\n\",\n      \"email_size\": 193,\n      \"is_read\": true,\n      \"created_at\": \"2013-08-25T19:32:07.576+03:00\",\n      \"updated_at\": \"2013-08-25T19:32:09.232+03:00\",\n      \"sent_at_timestamp\": 1377448326\n    }\n  ]\n```\n\nthis is MailTrap email format.\n\nAttachments should be returned as an array of objects with given schema:\n\n```javascript\n  [\n    {\n      \"id\": 1737,\n      \"message_id\": 54508,\n      \"filename\": \"Photos.png\",\n      \"attachment_type\": \"attachment\",\n      \"content_type\": \"image/png\",\n      \"content_id\": \"\",\n      \"transfer_encoding\": \"base64\",\n      \"attachment_size\": 213855,\n      \"created_at\": \"2013-08-16T00:39:34.677+03:00\",\n      \"updated_at\": \"2013-08-16T00:39:34.677+03:00\",\n      \"attachment_human_size\": \"210 KB\",\n      \"download_path\": \"/api/v1/inboxes/3/messages/54508/attachments/1737/download\"\n    }\n  ]\n```\n\nthis is MailTrap attachment format.\n"
  },
  {
    "path": "docs/headless.md",
    "content": "---\nid: headless\ntitle: Headless\n---\n\n# Headless browser control\n\nCurrently only Firefox and Google Chrome browser can be run headless.\n\nFor the rest of the supported browsers this flag is ignored.\n\nTo control headless via command line:\n- `npm run kakunin -- --headless` opens browser in headless mode\n- `npm run kakunin -- --headless=true` opens browser in headless mode\n- `npm run kakunin -- --headless=false` opens browser in normal mode\n\nAlso, there is a possibility to set `\"headless: \"true\"` or `\"headless: \"false\"` in the `kakunin.conf.js` config file. \n\n<span style=\"color:red\">Keep in mind that CLI has greater prority than the cofig file (overides settings on runtime).</span>\n"
  },
  {
    "path": "docs/hooks.md",
    "content": "---\nid: hooks\ntitle: Hooks\n---\n# Hooks for Kakunin tests\n\nThis section explains how to add priority hooks for kakunin tests based on the built-in adapter.\nHooks allow you to perform actions before and after scenario. \nFor example, it lets you clear all files from the downloads folder.\n\n\n\n## How to add hook with priority:\n##### initializeHook()\n - this method is provided to execute hook logic.\n##### getPriority()\n - this method returns numeric value and then it's sorted in order.\n\n```text \nRemember that new Hook must contain these 2 methods to fulfill interface.\n```\n\nAfter your hook is ready to use method `hookHandlers.addHook(Hook object)`\n\n\n### Example of example.hook.js:\n```typescript\nconst { hookHandlers, Before } = require('kakunin');\n\nclass ExampleHook {\n  initializeHook() {\n    Before(() => {\n      console.log('This hook is going to be 5th in order');\n    });\n  }\n\n  getPriority() {\n    return 5;\n  }\n}\n\nhookHandlers.addHook(new ExampleHook());\n```\n\n### Build in hooks:\n\n#### Clear download: \n  - Clears download folder before or/and after scenario. To use them add `@downloadClearBefore` or `@downloadClearAfter` tag.\n  Its priority is set to 1.\n#### Reload fixtures: \n  - allows you to reload fixtures before the desired scenario, via URL provided in `.env` file.\n  Its priority is set to 2.\n#### Take a screenshot and clear variables:\n  - These hooks are used by kakunin mechanism to clear variable store and take screenshots after scenarios.\n    Their priority is set to 1.\n"
  },
  {
    "path": "docs/how-it-works.md",
    "content": "---\nid: how-it-works\ntitle: How it works\n---\n\nKakunin is built with `no-js` experience in mind. Because of that you're able to test even complicated apps just\nby knowing Kakunin (Gherkin) steps and a few good practices.\n\n## Concepts\n\nKakunin uses `cucumber-js` internally, because of that all tests (or rather scenarios) are using `Gherkin` as a \"programming\"\nlanguage.\n\nA simple scenario could look like this:\n\n```gherkin\nFeature:\n    Scenario: Display user profile for logged user\n        Given I am logged in as a \"user\"\n        When the \"dashboard\" page is displayed\n        And I click the \"profileButton\" element\n        Then the \"myProfile\" page is displayed\n        And the \"myName\" element is visible\n```\n\nThis is how most of Kakunin test scenarios look like.\n\nThere are a few concepts to be explained.\n\n\n## Page objects\n\nPage object is a code representation of a page displayed in browser. Kakunin has built-in `BasePage` page object, that you should extend.\n\nPage object contains information about page url, its elements, locators, but can also have some custom methods if necessary.\n\nA very simple example of Kakunin's Page Object could look like the following:\n\n```javascript\nconst { BasePage } = require('kakunin');\n\nclass DashboardPage extends BasePage {\n    constructor() {\n        super();\n        \n        this.url = '/dashboard';\n    }\n}\n\nmodule.exports = DashboardPage;\n```\n\nAs you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (`this.url`).\n \nThis code should be saved inside `pages` directory in a file with `js` extension. \nNote that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:\n```gherkin\nWhen the \"dashboard\" page is displayed\n``` \nexpects that there is a file named `dashboard.js` inside the `pages` directory. \n\n\nEvery step that we are using is somehow connected to an object called `currentPage`. This object value is set to a \npage object that we expect to be on.\n\nThis is done by two kinds of steps:\n\n* `Then the \"dashboard\" page is displayed` - this one checks if current url in browser is the same as the one inside Page Object and changes a value of the `currentPage` field\n to this page object\n* `When I visit the \"dashboard\" page` - this one goes to the url specified in Page Object and attaches the Page Object to the `currentPage` field as above \n\nThis concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods.\nFor example, having the following code:\n\n```gherkin \nFeature:\n    Scenario: Display user profile for logged user\n        Given I am logged in as a \"user\"\n        When the \"dashboard\" page is displayed\n        And I click the \"profileButton\" element\n        Then the \"myProfile\" page is displayed\n        And the \"myName\" element is visible\n```\n\nThe step named `And I click the \"profileButton\" element` is executed in context of `dashboard` Page Object, thus we can assume that `profileButton` should be defined inside the\n`pages/dashboard.js` file.\n\nAt the same time the step `And the \"myName\" element is visible` is executed in context of `myProfile`, so `myName` should be defined in `pages/myProfile.js` file.\n\n\n## Elements and locators\n\nThe second concept that you have to understand are elements and locators.\n\nEvery element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:\n`And the \"myName\" element is visible`.\n\nDefining elements is very simple. Let's say we have such page object:\n\n``` \nconst { BasePage } = require('kakunin');\n\nclass DashboardPage extends BasePage {\n    constructor() {\n        super();\n        \n        this.url = '/dashboard';\n    }\n}\n\nmodule.exports = DashboardPage;\n```\n\nElements should be defined inside `constructor` method. Let's add element for `myName`:\n\n``` \nconst { BasePage } = require('kakunin');\n\nclass DashboardPage extends BasePage {\n    constructor() {\n        super();\n        \n        this.url = '/dashboard';\n        \n        this.myName = element(by.css('.myName'));\n    }\n}\n\nmodule.exports = DashboardPage;\n```\n\nAs you see we added a single line `this.myName = element(by.css('.myName'));`.\n\n`by.css('.myName')` - is a locator, this is a standard protractor syntax, you can read more on protractors documentation\n\nBy joining `element` method with a locator, we created element to be used by our steps.\n\n\n## Compare URLs examples:\n\n\n  | Page Object URL                                             | Current Browser URL                               | Base URL - config file    | Results   |\n  | ----------------------------------------------------------- | ------------------------------------------------- | ------------------------- | --------- |\n  | http://localhost:8080/incorrect-data                        | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | http://localhost:8080/incorrect-data/                       | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | http://google/incorrect-data                                | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | http://google/tabular-data                                  | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | http://google/incorrect-data/                               | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | /incorrect-data                                             | http://website.com/tabular-data                   | https://example-url.com   | FALSE     |\n  | /incorrect-data/                                            | http://website.com/tabular-data                   | http://incorrect.com      | FALSE     |\n  | http://localhost:8080/tabular-data                          | http://localhost:8080/tabular-data                | https://example-url.com   | TRUE      |\n  | http://localhost:8080/tabular-data/                         | http://localhost:8080/tabular-data                | http://localhost:8080     | TRUE      |\n  | /tabular-data                                               | http://localhost:8080/tabular-data                | http://localhost:8080     | TRUE      |\n  | /tabular-data/                                              | http://localhost:8080/tabular-data                | http://localhost:8080     | TRUE      |\n  | /tabular-data                                               | http://localhost:8080/tabular-data                | https://google.pl         | FALSE     |\n  | /tabular-data/                                              | http://localhost:8080/tabular-data                | https://google.pl         | FALSE     |\n  | /                                                           | https://google.pl/new                             | https://google.pl         | FALSE     |\n  |                                                             | https://google.pl/new                             | https://google.pl         | FALSE     |\n  |                                                             | http://localhost:8080                             | http://localhost:8080     | TRUE      |\n  | /                                                           | https://google.pl                                 | https://google.com        | FALSE     |\n  | https://google.com/:example/:name                           | https://google.com/example/janek                  | https://example-url.com   | TRUE      |\n  | https://google.com/:name                                    | https://google.com/janek                          | https://example-url.com   | TRUE      |\n  | https://google.com/account/:username/settings/display       | https://google.com/account/janek/settings/display | https://example-url.com   | TRUE      |\n  | /account/settings/:userType                                 | https://incorrect-host/account/settings/admin     | https://google.com        | FALSE     |\n  | /account/settings/:userType/something                       | https://incorrect-host/account/settings/admin     | https://example-url.com   | FALSE     |\n  | https://incorrect-host/account/settings/:userType/something | https://incorrect-host/account/settings/admin     | https://example-url.com   | FALSE     |\n  | /account/settings/:userType                                 | https://google.com/account/settings/user          | https://google.com        | TRUE      |\n"
  },
  {
    "path": "docs/index.md",
    "content": "---\nid: index\ntitle: Getting started\n---\n\n## About Kakunin\n\nKakunin is a Protractor extension created by The Software House sp. z o.o. and Takamol Holding. It allows you\nto write e2e test scenarios with a help of Gherkin language and JavaScript for all kind of applications - Angular, React and others.\n\n## Installation\n\nIn order to install Kakunin you have to make sure that you have installed:\n\n```text\nnode.js - v7.8.0 min\nJDK\nChrome\n```\n  \nCreate directory for your project\n```bash\nmkdir my_project\n```\n    \nGo to project directory \n```bash\ncd my_project\n```\n    \nInitialize JavaScript project\n```bash\nnpm init\n```\n\nInstall dependencies\n```bash\nnpm install cross-env kakunin --save\n```\n    \nInside `package.json` file; add new script in `scripts` section:\n```json\n\"kakunin\": \"cross-env NODE_ENV=prod kakunin\"\n``` \n\n## Configuration\n\n* Create kakunin project\n```bash\nnpm run kakunin init\n```\nThe above command will run Kakunin's init script.\n* Answer what kind of app you're going to test (`default: AngularJS`)\n* Enter URL where your tested app will be running (`default: http://localhost:3000`)\n* Choose if you plan to use some emails checking service (`default: none`)\n\nAlso, there is a possibility to answer these question by a command line.\n```text\nnpm run kakunin init -- --baseUrl https://google.com --type otherWeb --emailType none\n```\nAvailable parameters: `baseUrl`, `type`, `emailType`, `emailApiKey`, `emailInboxId`.\nYou will not be asked about question that you already answered by a command.\n\nAfter the init process, a project files should be automatically created in your directory.\n\nThis is an example of a console output after the init process is completed:\n```text\nCreated file at path /Users/example-user/projects/test/kakunin.conf.js\nCreated directory at path /Users/<user>/TSHProjects/test/reports\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report/features\nCreated directory at path /Users/<user>/TSHProjects/test/reports/performance\nCreated directory at path /Users/<user>/TSHProjects/test/downloads\nCreated directory at path /Users/example-user/projects/test/data\nCreated directory at path /Users/example-user/projects/test/features\nCreated directory at path /Users/example-user/projects/test/pages\nCreated directory at path /Users/example-user/projects/test/matchers\nCreated directory at path /Users/example-user/projects/test/generators\nCreated directory at path /Users/example-user/projects/test/form_handlers\nCreated directory at path /Users/example-user/projects/test/step_definitions\nCreated directory at path /Users/example-user/projects/test/comparators\nCreated directory at path /Users/example-user/projects/test/dictionaries\nCreated directory at path /Users/example-user/projects/test/regexes\nCreated directory at path /Users/example-user/projects/test/hooks\nCreated directory at path /Users/example-user/projects/test/transformers\nCreated directory at path /Users/example-user/projects/test/emails\nCreated file at path /Users/example-user/projects/test/downloads/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/features/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/performance/.gitkeep\nCreated file at path /Users/example-user/projects/test/features/example.feature\nCreated file at path /Users/example-user/projects/test/pages/page.js\nCreated file at path /Users/example-user/projects/test/matchers/matcher.js\nCreated file at path /Users/example-user/projects/test/generators/generator.js\nCreated file at path /Users/example-user/projects/test/step_definitions/steps.js\nCreated file at path /Users/example-user/projects/test/regexes/regex.js\nCreated file at path /Users/example-user/projects/test/hooks/hook.js\n```\n\nAnd you're set! Now you can run the tests using Kakunin:\n\n```bash\nnpm run kakunin\n```\n  \n  \n## Commands\n\n* Create a new project by answering few simple questions (you can pass additional parameter to enter advanced mode where you can configure all Kakunin options by yourself)\n\n    ```bash \n    npm run kakunin init [-- --advanced]\n    ``` \n* Run test scenarios\n\n    ```bash\n    npm run kakunin\n    ```\n* Run only scenarios tagged by `@someTag`\n\n     ```bash\n     npm run kakunin -- --tags @someTag\n     ``` \n* Run only scenarios tagged by `@someTag` and `@otherTag` at the same time\n \n    ```bash\n    npm run kakunin -- --tags \"@someTag and @otherTag\"\n    ```\n \n* Run only scenarios tagged by `@someTag` or `@otherTag`\n     \n     ```bash\n     npm run kakunin -- --tags \"@someTag or @otherTag\"\n     ```\n  \n* Run only scenarios not tagged by `@someTag` \n\n    ```bash\n    npm run kakunin -- --tags \"not @someTag\"\n    ```\n\n## Troubleshooting & Tips\n\nIn order to make cucumber steps autosuggestion work properly in JetBrains tools, make sure your project is `ECMAScript 6` compatible and you have `cucumberjs` plugin installed.\nDue to non-resolved issue in Jetbrains editors ([see here](https://youtrack.jetbrains.com/issue/WEB-11505)) we'll have to do one more step:\n \nGo to `step_definitions` directory \n```bash\ncd step_definitions\n``` \n\nPaste this code into terminal and restart your IDE:\n\nFor Linux/MacOs:\n\n```bash\nln -s ../node_modules/kakunin/src/step_definitions/elements.ts kakunin-elements.ts\nln -s ../node_modules/kakunin/src/step_definitions/debug.ts kakunin-debug.ts\nln -s ../node_modules/kakunin/src/step_definitions/file.ts kakunin-file.ts\nln -s ../node_modules/kakunin/src/step_definitions/form.ts kakunin-form.ts\nln -s ../node_modules/kakunin/src/step_definitions/email.ts kakunin-email.ts\nln -s ../node_modules/kakunin/src/step_definitions/generators.ts kakunin-generators.ts\nln -s ../node_modules/kakunin/src/step_definitions/navigation.ts kakunin-navigation.ts \nln -s ../node_modules/kakunin/src/step_definitions/performance.ts kakunin-performance.ts \n```\n\nFor Windows 8+: (you have to do this as administrator)\n\n```bash\nmklink kakunin-elements.ts ../node_modules/kakunin/src/step_definitions/elements.ts\nmklink kakunin-debug.ts ../node_modules/kakunin/src/step_definitions/debug.ts \nmklink kakunin-file.ts ../node_modules/kakunin/src/step_definitions/file.ts \nmklink kakunin-form.ts ../node_modules/kakunin/src/step_definitions/form.ts \nmklink kakunin-email.ts ../node_modules/kakunin/src/step_definitions/email.ts\nmklink kakunin-generators.ts ../node_modules/kakunin/src/step_definitions/generators.ts \nmklink kakunin-navigation.ts ../node_modules/kakunin/src/step_definitions/navigation.ts \nmklink kakunin-performance.ts ../node_modules/kakunin/src/step_definitions/performance.ts \n```\n\nKeep in mind that `mklink` is not available in older Windows distributions.\n\nThis will create symlinks inside `step_definitions` directory and make `cucumberjs` plugin recognize kakunin built-in steps.\n"
  },
  {
    "path": "docs/matchers.md",
    "content": "---\nid: matchers\ntitle: Matchers\n---\n\nMatchers allows you to check if a element content matches your expectation.\n\nFor example you can check if a value has a specified pattern or if a button is clickable.\n\nUsing matcher is very straightforward, for example: `f:isClickable`.\n\nMatchers can be used in most of the steps related to checking content (with exception of checking form values).\n\nKakunin comes with a set of built in matchers:\n\n## Visibility matcher\n\n`f:isVisible` - checks if element is visible (must be in viewport and cannot be hidden behind any other element)\n\n## Invisibility matcher\n\n`f:isNotVisible` - checks if element is not visible\n\n## Present matcher\n\n`f:isPresent` - checks if element is in html code (does not have to be visible)\n\n## Clickable matcher\n\n`f:isClickable` - checks if element is clickable\n\n## Not clickable matcher\n\n`f:isNotClickable` - checks if element is not clickable\n\n## Attribute matcher\n\n`attribute:attributeName:regexName` - allows to check if element has attribute with a name specified by `attributeName` and it has to \nhave a format passing `regexName`\n\nFor example, if there is an element:\n\n`<p custom-attribute=\"123123\">some value</p>`\n\nyou can check if attribute is an number by running: `attribute:custom-attribute:number`\n\n## Regex matcher\n\n`r:regexName` - allows you to run a `regexName` against a text value of element\n\nRegexes have to be specified inside `regex` directory or be a kakunin built ones:\n\n`notEmpty` - there must be a value\n`number` - must be a number\n\nYou can add your own matchers. In order to do so please read `Extending Kakunin` section.\n\n## Text matcher\n\n`t:text you are looking for` - allows you to check if an element contains a expected text\n\n## Current date matcher\n\n`f:currentDate:{format}` - allows you to generate current date, `{format}` is optional, by default `DD-MM-YYYY`"
  },
  {
    "path": "docs/parallel-testing.md",
    "content": "---\nid: parallel-testing\ntitle: Parallel testing\n---\nThere is a possibility to run tests in parallel.\n\n## How to execute\nUse a command `npm run kakunin -- --parallel <number of instances>` where `number of instances` is a number.\n\nExample:\n- `npm run kakunin -- --chrome --parallel 2`\n\n<span style=\"color:red\">Keep in mind that the merged report is available in the `reports/report/index.html` file. text</span>\n\n## Specify pattern per each instance\n- `npm run kakunin -- --parallel <number of instances> --pattern <regex to much feature> --pattern <regex to much feature>`\n\nKeep in mind that:\n\n- the number given in `parallel` must be equal to passed `patterns`\n- `<number of instances>` is a number of instances of the specified browser\n- `<regex>` is a pattern that is used to specify the list of specs that will be executed in each of the instances\n-----------------------------------------------------------------------------------\n\n## Troubleshooting\n1. Running more than one instance in `Firefox` is not possible now (fix in-progress).\n"
  },
  {
    "path": "docs/performance-testing.md",
    "content": "---\nid: performance-testing\ntitle: Performance testing\n---\n\nPerformance testing is possible thanks to `browsermob-proxy`.\n\nIt saves all data from network tab (Google Chrome console) which is generated during the test.\n\nThere is a possibility to compare `TTFB` value with a maximum given one. \n\n`TTFB` (Time to first byte) measures the duration from the client making an HTTP request to the first byte of a response being received by the client's browser.\n\nMore details can be found in documentation - `Built-in steps` section.\n\n# What needs to be done?\n\n## Get started\n\n1. Download `browsermob-proxy` from `https://github.com/lightbody/browsermob-proxy`\n\n2. Navigate in terminal to the catalog\n\n3. Use following command to start the REST API\n\n```\n./browsermob-proxy -port 8887\n```\n\n## Configuration\n1. Add `browsermob-proxy` configuration to `kakunin.conf.js`\n\nYou can use one of the following methods to configure browsermob-proxy:\n\n- `npm run kakunin init -- --advanced` and go through the process\n\n- or add it manually to the config file:\n\n```javascript\n    \"browserMob\": {\n      \"serverPort\": 8887,\n      \"port\": 8888,\n      \"host\": \"localhost\"\n    }\n```\n\n## Run tests\n\n1. `performance steps` must be used in the scenario where you are testing performance\n\n2. Scenario must have a tag `@performance`\n\n3. Run tests with special parameter:\n\n```\nnpm run kakunin -- --performance\n```\n\n## Results\n\n1. `.har` files are saved in catalog `reports/performance/*.har`\n"
  },
  {
    "path": "docs/quickstart.md",
    "content": "---\nid: quickstart\ntitle: Quick start\n---\nAs a quick demonstration of the framework let's test the \n[React variant of TodoMVC](http://todomvc.com/examples/react/#/) project. \nOf course other testing other frameworks is possible, you can try it \nby yourself!\n\n## Install packages\nIn order to install Kakunin you have to make sure that you have installed:\n\n```text\nnode.js - v7.8.0 min\nJDK\nChrome\n```\n  \nCreate directory for your project and enter it\n\n```bash\n$mkdir my_project\ncd my_project\n```\n    \nInitialize JavaScript project\n```bash\nnpm init\n```\n\nInstall dependencies\n\n```bash\nnpm install cross-env kakunin --save\n```\n\nInside `package.json` file add new script in `scripts` section:\n```js\n...\n\"scripts\": {\n  \"kakunin\": \"cross-env NODE_ENV=prod kakunin\"\n},\n...\n```\n\n## Configure Kakunin\nRun initialization command \n\n```bash\nnpm run kakunin init\n```\n\nAnswer literally few questions:\n\n```text\nWhat kind of application would you like to test? : otherWeb\n        \nWhat is base url? [http://localhost:3000]: http://todomvc.com\n           \nWhat kind of email service would you like to use?: none\n```  \nAnd you're set! Now let's write some test!\n\n## Test the app\n\nCreate a page object that will contain instructions on how to locate elements in the projects.\nCreate a file `pages/main.js`:\n\n```javascript\nconst { BasePage } = require('kakunin');\n\nclass MainPage extends BasePage {\n    constructor() {\n        super();\n\n        // define the main url for the page\n        this.url = '/examples/react/#/';\n\n        // whole form tag\n        this.addTodoForm = $('.todoapp');\n\n        // input field\n        this.todoInput = $('input.new-todo');\n\n        // list of currently added todos\n        this.todos = $$('.todo-list .view');\n        this.todoLabel = by.css('label');\n\n        // first todo item in a list\n        this.firstTodoItem = this.todos.get(0);\n    }\n}\n\nmodule.exports = MainPage;\n```\n\nNow that we have prepared the locators, we can start writing our test. Let's test adding new todo item. \n\nCreate a file named: `features/adding_todo.feature` with the following contents:\n\n```gherkin\nFeature:\n\n    Scenario: Adding todo\n        Given I visit the \"main\" page\n        And I wait for \"visibilityOf\" of the \"addTodoForm\" element\n        And the \"addTodoForm\" element is visible\n        When I fill the \"addTodoForm\" form with:\n            | todoInput | My new todo |\n        And I press the \"enter\" key\n        Then there are \"equal 1\" \"todos\" elements\n\n```\n\nAnd that's it! All you have to do now is to run the test and watch the magic happens ;)\n\n```bash\nnpm run kakunin\n```\n\nThe tests may run quite fast so you might not been able to see that it \nreally works as expected. To check if the todo items has been really \nadded to the list, let's use a simple hack - let's pause the running \ntest right after the todo has been added. \n\nTo do that, let's upgrade our Scenario. Update the file:\n```gherkin\nFeature:\n\n    Scenario: Adding todo\n        Given I visit the \"main\" page\n        And I wait for \"visibilityOf\" of the \"addTodoForm\" element\n        And the \"addTodoForm\" element is visible\n        When I fill the \"addTodoForm\" form with:\n            | todoInput | My new todo |\n        And I wait for \"1\" seconds\n        And I press the \"enter\" key\n        When I fill the \"addTodoForm\" form with:\n            | todoInput | Another todo item! |\n        And I wait for \"1\" seconds\n        And I press the \"enter\" key\n        Then there are \"equal 2\" \"todos\" elements\n        Then I wait for \"5\" seconds\n\n``` \n\nAs you can see, we've added 1 new step that waits for a second before \n\"pressing\" the `enter` key. We've also added a second todo item with \na short pause at the end of the test so you can see the changes.\n\nIf you want to see what can we do more with the TodoMVC project, take a look \nat the `example` dir, where you'll find a complete set of test for the project.\n"
  },
  {
    "path": "docs/steps-debug.md",
    "content": "---\nid: steps-debug\ntitle: Debug\n---\n\n# Steps for debugging application:\n\n## `I pause`\n\nPauses tests execution and allows to continue manually by pressing combination of `ctrl+c` inside terminal.\n\n---\n\n## `I wait for \":seconds\" seconds`\n\nWaits with execution of next step for an amount provided by parameter `:seconds`.\n\n---\n\n## `I start performance monitor mode`\n\nIt starts performance monitor mode.\n\nKeep in mind that REST API must be started on the port which must configured in `kakunin.conf.js` - `serverPort: 8887`.\n\nMore details can be found in documentation file `performance-testing.md`.\n\n---\n\n## `I save performance report file as \"fileName\"`\n\nIt saves `.har` file with a name `fileName` in `reports/performance` catalog.\n\nFor example: `exampleReport-1511470954552.har`\n\nData is generated during the test - network tab in Chrome Chrome console.\n\nKeep in mind:\n\n* `I start performance monitor mode` must be used before this step\n\n* `browserMob.port` must be configured in `kakunin.conf.js`\n\n* `browserMob.host` must be configured in `kakunin.conf.js`\n\nMore details can be found in documentation file `performance-testing.md`.\n\n---\n\n## `the requests should take a maximum of \"maxTiming\" milliseconds`\n\nIt compares every `TTFB` timing value from previously saved `.har` report with a `maxTiming` value.\n\nSlow requests are listed in your terminal in red colour.\n\nKeep in mind that `I start performance monitor mode` and `I save performance report file as \"fileName\"` steps must be executed before this one!\n\n---\n"
  },
  {
    "path": "docs/steps-elements.md",
    "content": "---\nid: steps-elements\ntitle: Elements\n---\n\n# Steps used to interact with elements:\n## `I infinitely scroll to the \":elementName\" element`\n\nAllows to scroll through infinite scroll mechanism.\n\nThe `:elementName` is a name of a selector for loading trigger.\n\n---\n\n## `I wait for \":expectedConditionName\" of the \":elementName\" element`\n\nWaits till element `:elementName` from `this.currentPage` meets criteria specified by `:expectedConditionName`.\n\nYou can use any of the Protractor's expected condition:\n\n* `visibilityOf`\n* `invisibilityOf`\n\netc.\n\nRead more in Protractor's API documentation.\n\n---\n\n## `I wait for the \":elementName\" element to disappear`\n\nWaits till element `:elementName` disappears.\n\n---\n\n## `I scroll to the \":elementName\" element`\n\nScrolls to element `:elementName` of `this.currentPage`. The element will be on bottom of the page.\n\n---\n\n## `I infinitely scroll to the \":elementName\" element`\n\nAllows to scroll till `:elementName` is visible. Useful for infinite scrolling functionality.\n\n---\n\n## `I press the \":keyName\" key`\n\nPerforms a key press operation on `:keyName` key.\n\n---\n\n## `I click the \":elementName\" element`\n\nPerforms a click action on element `:elementName` from `this.currentPage'\n\nThe child element must be specified by `:elementName` and must be available in `this.currentPage`.\n\n---\n\n## `I store the \":elementName\" element text as \":variableName\" variable`\n\nStores the text from element `:elementName` of `this.currentPage` under the `:variableName` so you can use it later.\n\n---\n\n## `I update the \":elementName\" element text as \":variableName\" variable`\n\nUpdates the variable `:variableName` value by value from element `:elementName` of `this.currentPage`.\n\n---\n\n## `I store the \":elementName\" element text matched by \":matchingRegex\" as \":variableName\" variable`\n\nStores the part of the element `:elementName` text, that matches the `:matchingRegex` under the `:variableName` for later use.\n\n---\n## `the \":elementName\"\" element is visible`\n\nChecks if element `:elementName` is visible and clickable\n\n---\n\n## `the \":elementName\"\" element is not visible`\n\nChecks if element `:elementName` is available in HTML DOM but is not visible and clickable\n\n---\n\n## `the \":elementName\" element is disabled`\n\nChecks if element is disabled\n\n---\n\n## `I store table \":tableRow\" rows as \":variableName\" with columns:`\n\nAllows to store a row specified columns from a table `:tableRow` and save it under `:variableName` as an array of objects.\n\nThis step requires a table of columns elements, for example:\n\n```gherkin\nI store table \"someRow\" rows as \"someVariable\" with columns:\n  | firstName |\n  | lastName  |\n  | id        |\n```\n\nIn order to make it work there must be not only array element `this.someRow = $$('.rows')` in `this.currentPage`, but also\nelement `this.firstName = $('.firstName');` and so on.\n\nThe result of this step is an array of:\n\n```javascript\n[\n  [\n    'firsRowFirstNameValue',\n    'firsRowLastNameValue'\n    'firsRowIdValue'\n  ]\n  ...\n]\n```\n\n---\n\n## `there are following elements in table \":elementName\":`\n\nAllows to check if a child elements of `:elementName` have a specified content.\n\nThis steps allows you to specify an array of child elements that will be checked against expected values.\n\nFor example:\n\n```gherkin\nthere are following elements in table \"myTable\":\n  | id  | firstName | lastName |\n  | t:1 | t:Adam    | t:Doe    |\n  | t:2 | t:John    | t:Doe    |\n```\n\nFirst row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.\n\nThis step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.\n\nWe can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).\n\n---\n\n## `there are \"numberExpression\" following elements for element \":elementName\":`\n\nAllows to check if a child elements of `:elementName` have a specified content. Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nAllows to check if a number of elements is the one that we expect.\n\n`numberExpression` is a supported expression from `chai.js` library:\n\n* `equal N` where N is a number\n\n* `at least N` where N is a number\n\n* `above N` where N is a number\n\n* `below N` where N is a number\n\n* `within N M` where N and M are a numbers\n\nand so on. You can check expressions on `chai.js` API dock for BDD.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthere are \"equal 5\" following elements for element \"myList\":\n  | viewButton | f:isClickable |\n  | id         | r:idRegex     |\n```\n\nThe child elements must be an elements, for example `this.viewButton = $('button.viewButton');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `there are \":elementName\" dropdown list elements with following options:`\n\nAllows to check if there is exact match to options provided in table for option selector. \n```html\n<select name=\"list\" id=\"personlist\">\n  <option value=\"1\">Person 1</option>\n  <option value=\"2\">Person 2</option>\n  <option value=\"3\">Person 3</option>\n  <option value=\"4\">Person 4</option>\n</select>\n```\nFor example:\n\n```gherkin\nthere are \"personOption\" dropdown list elements with following options:\n  | Person 1      |\n  | Person 2      |\n  | Person 3      |\n  | Person 4      |\n```\nThe element must be for example:  \n`this.personOption = this.personForm.$$('option');`.\n\n---\n\n## `there is element \":elementName\" with value \":matcher\"`\n\nAllows to check if `:elementName` has a value that matches the `:matcher`.\n\n---\n\n## `there is element \":elementName\" containing \":matcher\" text`\n\nAllows to check if `:elementName` contains a text that matches the `:matcher`.\n\n---\n\n## `there is element \":elementName\" matching \":matcher\" matcher`\n\nAllows to check if `:elementName` matches the given type of `:matcher`. For example:\n\n```gherkin\nthere is element \"button\" matching \"isClickable\" matcher\n```\n\n---\n\n## `there is element \":elementName\" with regex \":matcher\"`\n\nAllows to check if `:elementName` matches given type of regex. For example:\n\n```gherkin\nthere is element \"input\" with regex \"notEmpty\"\n```\n\n---\n\n## `there is no element \":elementName\" with value \":matcherName\"`\n\nAllows to check if there is no `:elementName` that matches the `:matcher`.\n\n---\n\n## `there is no element \":elementName\" containing \":matcher\" text`\n\nAllows to check if `:elementName` doesn't contain a text that matches the `:matcher`.\n\n---\n\n## `there is no element \":elementName\" matching \":matcher\" matcher`\n\nAllows to check if `:elementName` is not matching the given type of `:matcher`.\n\n---\n\n## `there is no element \":elementName\" with regex \":matcher\"`\n\nAllows to check if `:elementName` is not matching given type of regex.\n\n---\n\n## `there are \"numberExpression\" \":elementName\" elements`\n\nAllows to check if a number of `:elementName` elements is the same as we expect.\n\n`numberExpression` is a supported expression from `chai.js` library:\n\n* `equal N` where N is a number\n\n* `at least N` where N is a number\n\n* `above N` where N is a number\n\n* `below N` where N is a number\n\n* `within N M` where N and M are a numbers\n\nand so on. You can check expressions on `chai.js` API dock for BDD.\n\n`:elementName` should be specified as an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\n---\n\n## `every \":elementName\" element should have the same value for element \":columnElementName\"`\n\nAllows to check if every row defined by `:elementName` has the same value for a column `:columnElementName`.\n\n`:elementName` must be an array of elements\n\n`:columnElementName` must be an element, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>1</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')` and we can specify column element\n`this.myColumn = $('td');`. This allows us to write:\n\n`every \"myElement\" element should have the same value for element \"myColumn\"`\n\n---\n\n## `the element \":elementName\" should have an item with values:`\n\nAllows to check if any of the child elements of `:elementName` have a specified content (one matching element is enough). Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthe element \"myList\" should have an item with values:\n  | id | t:1 |\n```\n\nThe child elements must be an elements, for example `this.id = $('td');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `the element \":elementName\" should not have an item with values:`\n\nAllows to check if the child elements of `:elementName` have a different content than that given in the table. Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthe element \"myList\" should have an item with values:\n  | id | t:does-not-exist |\n```\n\nThe child elements must be an elements, for example `this.id = $('td');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `I drag \":elementDrag\" element and drop over \":elementDrop\" element`\n\nClicks on `:elementDrag` and moves it onto `:elementDrop` while left mouse button is pressed, and then release it.\n\nNote: This step is not working on HTML5!\n\n---\n"
  },
  {
    "path": "docs/steps-files.md",
    "content": "---\nid: steps-files\ntitle: Files\n---\n\n\n# Steps used to interact with files:\n## `the file \":fileName\" should be downloaded`\n\nChecks if a file with name `:fileName` was downloaded.\n\nThis step does not support matchers or regular expressions, so the name must be exact match. However you can use\nvariable store here.\n\nLet's assume there is a variable `myFile` with a value `super-file` in variable store.\n\nYou can write `the file \"v:myFile.zip\" should be downloaded` to check if a file `super-file.zip` was downloaded.\n\n---\n\n## `the file \":fileName\" contains table data stored under \":variableName\" variable`\n\nThis step allows you to compare an xls/xlsx file `:fileName` with an existing data stored under `:variableName` variable.\n\nThe data under `:variableName` must be an array of objects representing each row of file.\n\n---\n"
  },
  {
    "path": "docs/steps-forms.md",
    "content": "---\nid: steps-forms\ntitle: Forms\n---\n\n# Steps used to fill forms:\n\n## `I fill the \":formName\" form with:`\n\nAllows to fill the form with the name `:formName` and values provided as an array of inputs and values. The element with name `:formName` must be defined inside the\n`currentPage` page object.\n\nInput and values should be provided as an array for example:\n\n```gherkin\nI fill the \"myForm\" form with:\n  | inputElement    | value to be typed into field        |\n  | textareaElement | value to be typed into textarea     |\n  | radioElement    | radio value to be selected          |\n  | checkboxElement | checkbox label value to be selected |\n```\n\nBy default we support all basic HTML field types (text inputs, checkboxes, radios, selects, files and textareas)\n\nIn order to use the default handlers the elements you use as input must follow pattern:\n\nFor inputs:\n\n`this.element = $('input')` - element should point at input you want to fill\n\nFor textareas:\n\n`this.element = $('textarea')` - element should point at textarea you want to fill\n\nFor file input:\n\n`this.element = $('input')` - element should point at input you want to fill and value should a filename of file from `data` directory\n\nFor selects:\n\n`this.element = $('select')` - element should point at select and value should be an value of expected option\n\nFor radios:\n\n`this.element = $$('radio[name=\"name-of-radio\"]')` - element should be an array of all radio input of given name and value should be an value of radio you wish to select\n\nFor checkboxes:\n\nCheckbox should have a html like:\n\n```html\n<label>\n  My checkbox\n  <input type=\"checkbox\" name=\"some-name\"/>\n</label>\n```\n\n`this.element = $$('checkbox[name=\"name-of-radio\"]')` - element should be an array of all checkboxes of given name and value should be a text from label of checkbox you want to fill\n\nYou can use all kind of transformers to as a values for fields.\n\n---\n\n## `the \":formName\" form is filled with:`\n\nThe same as `I fill the \":formName\" form with:` but allows to check if a form is filled with a given set of values.\n\nYou can use all kind of transformers to as a expected values for fields.\n\nThe only difference is for file fields. You cannot check uploaded files just like that, however we prepared a special type of handler\nthat allow to check for some information related to a specific file.\n\nLet's assume that after upload we display an information with a file name of a uploaded file.\n\nYou can use a special handler that requires to set a element with a postfix `Uploaded`. This will check if a value of that element is the same as you expected.\n\nFor example you can write a step like this:\n\n```gherkin\nthe \"myform\" form is filled with:\n  | myFileUploaded | file.txt |\n```\n\nKeep in mind that the element name must end with `Uploaded` for example:\n\n`this.myFileUploaded = $('p.some-file')`\n\n---\n\n## `the error messages should be displayed:`\n\nAllows you to specify the error messages that should be displayed for a specific elements.\n\nThis step requires an array of format:\n\n```gherkin\nthe error messages should be displayed:\n  | myElement | my error message |\n```\n\nYou can use dictionaries in this step as follows:\n\n```gherkin\nthe error messages should be displayed:\n  | myElement | d:dictionaryName:dictionaryKey |\n```\n\n---\n"
  },
  {
    "path": "docs/steps-generators.md",
    "content": "---\nid: steps-generators\ntitle: Generators\n---\n\n# Steps used to generate values:\n\n## `I generate random \":generator:param:param\" as \":variableName\"`\n \n\nAllows to generate a random value using the generator specified by `:generator:param:param`.\n\nThe generator must be defined inside the any of the `generators` directories specified in `kakunin.conf.js` file `default: generators`.\n\nIf the generator exists, then the value will be saved under the `:variableName` and can be accessed by:\n\n* steps using variable store\n\n* by calling `variableStore.getVariableValue(:variableName)`\n\n* by using variable store transformer on supported steps `v:variableName`\n\n---\n"
  },
  {
    "path": "docs/steps-navigation.md",
    "content": "---\nid: steps-navigation\ntitle: Navigation\n---\n\n# Steps used for navigation on page:\n\n## `I visit the \":pageFileName\" page`\n\nVisits the url of the page object with `:pageFileName` name.\n\nIn order to make it work we create a page object file with a name of `:pageFileName`.\n\nFor example in case of: `I visit the \"myPage\" page` there should be a file `myPage.js` inside the `pages` directory.\n\nIf we have a page object with a name `somePageObject.js` defined inside `pages` directory then:\n\n`Given I visit the \"somePageObject\" page`\n\nwill set `this.currentPage` variable to `somePageObject` page and we should end up on `somePageObject` url.\n\n---\n\n## `I visit the \":pageFileName\" page with parameters:`\n\nThe same as `I visit the \":pageFileName\" page` except allows to pass url parameters.\n\nIf url of `myPage` is defined as `this.url = /orders/:orderId/products/:productId` then we can use this step to visit this page by:\n\n```gherkin\nI visit the \"myPage\" page with parameters:\n    | orderId   | 1 |\n    | productId | 2 |\n```\n\nthis will result in visiting the `/orders/1/product/2` page.\n\n---\n\n## `the \":pageFileName\" page is displayed`\n\nChecks if current browser url matches url of `pageFileName` page object.\n\nIf the url matches expected pattern then\n`this.currentPage` variable is set to `pageFileName` page object.\n\n---\n"
  },
  {
    "path": "docs/steps-rest.md",
    "content": "---\nid: steps-rest\ntitle: Rest api\n---\n\n# Steps used for testing REST api:\n\nIn order to configure url for api, please change `apiUrl` field in `functional-tests/kakunin.conf.js`. This will set url of application api.\n\n## `I send \":methodName\" request on \":endpoint\" endpoint`\n\nSends to the given request method to given website endpoint.\n\nFor example, in case of GET request for /posts endpoint it should look like: \n```gherkin\nI send \"GET\" request on \"posts\" endpoint\n```\n\n## `^I send \":methodName\" request on \":endpoint\" endpoint with JSON body:`\n\nSends request method to website endpoint requiring JSON body.\n\n```gherkin\nI send \"POST\" request on \"posts\" endpoint with JSON body:\n    \"\"\"\n    {\n        \"title\": \"user\",\n        \"body\": \"test\"\n    }\n    \"\"\"\n```\n\n## `^I send \"methodName\" request on \":endpoint\" endpoint using form data:`\n\nSends request method to website endpoint using form data.\n\n```gherkin\nI send \"POST\" request on \"posts\" endpoint using form data:\n    | title | user |\n```\n\n## `the response code should be \":statusCode\"`\n\nVerifies if the server response code has match to given one.\n\n## `the response should exact match to body:`\n\nVerifies if the server response body has exact match to given one.\n\n```gherkin\nthe response should exact match to body:\n    \"\"\"\n    {\n        \"userId\": 1,\n        \"id\": 1,\n        \"title\": \"user\",\n        \"body\": \"test\"\n    }\n    \"\"\"\n```\n\n## `the response should match JSON schema:`\n\nVerifies if the server response body has exact match to given JSON schema.\n\n```gherkin\nthe response should exact match JSON schema:\n    \"\"\"\n    {\n        \"title\": \"Test schema\",\n        \"type\": \"object\",\n        \"properties\": {\n            \"id\": {\n                \"type\": \"integer\"\n            }\n        },\n        \"required\": [\"id\"]\n    }\n    \"\"\"\n```\n\n## `I set request headers:`\n\nSets the request headers to given one till creating new request.\n\n```gherkin\nI set request headers:\n    | Content-type | application/json |\n    | accept       | */*              |\n```\n"
  },
  {
    "path": "docs/testing-rest-api.md",
    "content": "---\nid: testing-rest-api\ntitle: REST API examples\n---\n\n# Testing REST API of your application\n\nIn this section examples of using steps provided for testing, REST API will be provided.\nAll examples can be checked on site https://reqres.in/ which is simple REST API service\n\n# Available methods\n\nAt this moment Kakunin supports methods for REST API:\n- GET\n- POST\n- DELETE\n- PATCH\n\nAlso, You can set the headers for the request.\n\n# Making GET request\n\nIn order to create get request and verify if the response is ok you need to create scenario step: \n\n```gherkin\nGiven I send \"GET\" request on \"/api/users/2\" endpoint\nThen the response code should be \"200\"\n```\n\nThis scenario will create a get request to the application and verify if the response was 200. \nThe response is stored till creating another request. So if We want to test the response body of a server we can create a scenario like:\n\n```gherkin\nGiven I send \"GET\" request on \"/api/users/2\" endpoint\nThen the response code should be \"200\"\nAnd the response should exact match to body:\n    \"\"\"\n    {\n        \"data\": {\n            \"id\": 2,\n            \"first_name\": \"Janet\",\n            \"last_name\": \"Weaver\",\n            \"avatar\": \"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg\"\n        }\n    }\n    \"\"\"\n```\n\nBased on this We can also check if the response matches schema that we have provided by using step:\n\n```gherkin\nThen the response should exact match JSON schema:\n```\n\n# Making POST request\n\nIn order to create post request and attach the JSON body to it You need to create a scenario:\n\n```gherkin\nGiven I send \"POST\" request on \"/api/users\" endpoint with body:\n  \"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"leader\"\n  }\n  \"\"\"\nThen the response code should be \"201\"\n```\n\nor you can create post request and attach the form data to it: \n\n```gherkin\nGiven I send \"POST\" request on \"/api/users\" endpoint using form data:\n  | name | morpheus |\nThen the response code should be \"201\"\n```\n\nThis scenario will create a post request to the application and verify if response was 201 (created). \nThe response is stored till creating another request. So if We want to test the response body of a server we can create scenarios\nlike before:\n\n```gherkin\nGiven I send \"POST\" request on \"/api/users\" endpoint with body:\n  \"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"leader\"\n  }\n  \"\"\"\nThen the response code should be \"201\"\nAnd the response should match JSON schema:\n  \"\"\"\n  {\n      \"title\": \"Post schema\",\n      \"type\": \"object\",\n      \"properties\": {\n          \"name\": {\n              \"type\": \"string\"\n          },\n          \"job\": {\n              \"type\": \"string\"\n          }\n      },\n      \"required\": [\"name\", \"job\"]\n  }\n  \"\"\"\n```\n\nScenario like that will verify if the post request was executed and response schema matches given one.\n\n# Making DELETE request\n\nDelete request works similarly to get request. Example of delete scenario:\n\n```gherkin\nGiven I send \"DELETE\" request on \"/api/users/2\" endpoint\nThen the response code should be \"204\"\n```\n\n# Making PATCH request\n\nPatch request works similarly to post request. Example of patch scenario: \n\n```gherkin\nGiven I send \"PATCH\" request on \"/api/users/2\" endpoint with JSON body:\n  \"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"zion resident\"\n  }\n  \"\"\"\nThen the response code should be \"200\"\nAnd the response should exact match to body:\n  \"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"zion resident\",\n      \"updatedAt\": \"2019-02-12T18:25:06.001Z\"\n  }\n  \"\"\"\n```\n\n# Setting headers for request\n\nSometimes We want to set the headers for next request. In order to achieve this, We can create scenario like:\n\n```gherkin\nGiven I set request headers:\n  | User-Agent | Mozilla |\nWhen I send \"POST\" request on \"postTestEndpoint\" endpoint with JSON body:\n  \"\"\"\n  {\n      \"title\": \"adam\",\n      \"body\": \"test\"\n  }\n  \"\"\"\nThen the response code should be \"403\"\n```\n This scenario will set \"User-Agent\" header of next request to \"Mozilla\".\n"
  },
  {
    "path": "docs/transformers.md",
    "content": "---\nid: transformers\ntitle: Transformers\n---\n\nTransformers allow you to transform values passed to form steps.\n\nFor example a select requires to pass a value `/options/1b30f17e-e445-4d28-a30c-dedad95829ab`. This one is quite unreadable, but with the help of transformers you are\nable to write it like this: `d:options:someOptionName`.\n\nIn real-life example it will look similar to:\n\n```gherkin \nI fill the \"myForm\" form with:\n  | inputElement    | d:someDictionary:someKey            |\n  | textareaElement | g:someGenerator                     |\n  | radioElement    | v:someVariableName                  |\n  | checkboxElement | standard value                      |\n```\n\nThere are 3 types of built-in transformers:\n\n## Dictionaries\n\nDictionaries allows you to transform a value A to value B using a simple key->value transformation.\n\nYou can run a dictionary transformer by providing dictionary prefix `d:`, specifying the dictionary name and key that should be used as a value provider. For example:\n\n`d:myDictionaryName:myDictionaryKey`\n\nthis example assumes that there is a dictionary that supports name `myDictionaryName` and it has `myDictionarKey` key.\n\nYou can read about dictionaries in `Extending Kakunin` section.\n\n## Generators\n\nGenerators allows you to generate a value by using a specified generator.\n\nThis can be done by: `g:generatorName`.\n\nIf a generator supports parameters then you can specify them by:\n\n`g:generatorName:param1:param2:...:paramN`\n\nYou can read more about generators in `Extending Kakunin` section.\n\n## Variable store\n\nVariable store allows you to fill the form with a value that was saved in previous steps of current running scenario.\n\nThis can be done by:\n\n`v:variableName`\n\nYou can read more about variable store in `Extending Kakunin` section\n"
  },
  {
    "path": "functional-tests/dictionaries/test-dictionary.js",
    "content": "const { dictionaries } = require('kakunin');\nconst { BaseDictionary } = require('kakunin');\n\nclass TestDictionary extends BaseDictionary {\n  constructor() {\n    super('test-dictionary', {\n      'test-name': 'Janek',\n      'test-value': 'lux',\n    });\n  }\n}\n\ndictionaries.addDictionary(new TestDictionary());\n"
  },
  {
    "path": "functional-tests/downloads/.gitkeep",
    "content": ""
  },
  {
    "path": "functional-tests/features/content/operations_on_stored_variables.feature",
    "content": "Feature: Store table and compare jsons\n    As a kakunin user\n    I want to store values as variables\n\n    Scenario: Store table and compare jsons\n        Given I visit the \"main\" page\n        When I click the \"tabularDataLink\" element\n        Then the \"tabularData\" page is displayed\n        When I store table \"rows\" rows as \"tableValue\" with columns:\n            | indexLocator    |\n            | descendingIndex |\n            | viewButton      |\n        Then compare given JSON string with stored \"tableValue\" JSON:\n            \"\"\"\n            [\n                [\"1\", \"4\", \"View\"],\n                [\"2\", \"3\", \"View\"],\n                [\"3\", \"2\", \"View\"],\n                [\"4\", \"1\", \"View\"]\n            ]\n            \"\"\"\n\n    Scenario: Compare stored values with the content from a xlsx file - equal rows and four stored values\n        Given I store the content from \"http://localhost:8080/xlsx/data-9rows\" endpoint as \"storedTable\" variable\n        Then the file \"example.xlsx\" contains table data stored under \"storedTable\" variable\n\n    Scenario: Compare stored values with the content from a xlsx file - equal rows and one stored value\n        Given I store the content from \"http://localhost:8080/xlsx/data-9rows-part\" endpoint as \"storedTable\" variable\n        Then the file \"example.xlsx\" contains table data stored under \"storedTable\" variable\n\n    Scenario: Compare stored values with the content from a xlsx file - three rows and four stored values\n        Given I store the content from \"http://localhost:8080/xlsx/data-3rows\" endpoint as \"storedTable\" variable\n        Then the file \"example.xlsx\" contains table data stored under \"storedTable\" variable\n\n    Scenario: Compare stored values with the content from a xlsx file - three rows and two stored values\n        Given I store the content from \"http://localhost:8080/xlsx/data-3rows-part\" endpoint as \"storedTable\" variable\n        Then the file \"example.xlsx\" contains table data stored under \"storedTable\" variable\n\n    Scenario: Compare stored values with the content from a xlsx file - one row and four stored values\n        Given I store the content from \"http://localhost:8080/xlsx/data-1row\" endpoint as \"storedTable\" variable\n        Then the file \"example.xlsx\" contains table data stored under \"storedTable\" variable\n\n    Scenario: Compare stored values with the content from a xlsx file - one row and two stored values\n        Given I store the content from \"http://localhost:8080/xlsx/data-1row-part\" endpoint as \"storedTable\" variable\n        Then the file \"example.xlsx\" contains table data stored under \"storedTable\" variable\n"
  },
  {
    "path": "functional-tests/features/content/validate_tabular_data.feature",
    "content": "Feature: Tabular data\n    As a kakunin user\n    I want validate tabular data\n\n    Scenario: Validate tabular data count\n        Given I visit the \"main\" page\n        When I click the \"tabularDataLink\" element\n        Then the \"tabularData\" page is displayed\n        And there are \"at least 1\" \"rows\" elements\n        And there are \"above 3\" \"rows\" elements\n        And there are \"below 5\" \"rows\" elements\n        And there are \"within 3 5\" \"rows\" elements\n        And there are \"equal 4\" \"rows\" elements\n\n    Scenario: Validate tabular data count and content, also check sorting\n        Given I visit the \"main\" page\n        When I click the \"tabularDataLink\" element\n        Then the \"tabularData\" page is displayed\n        And the \"rows\" element is visible\n        And there are \"at least 4\" following elements for element \"rows\":\n            | indexLocator | r:validNumber   |\n        And there are \"above 3\" following elements for element \"rows\":\n            | indexLocator | r:validNumber   |\n        And there are \"equal 4\" following elements for element \"rows\":\n            | indexLocator | r:validNumber   |\n        And there are \"below 5\" following elements for element \"rows\":\n            | indexLocator | r:validNumber   |\n        And there are \"within 3-5\" following elements for element \"rows\":\n            | indexLocator | r:validNumber   |\n        And there are \"equal 4\" following elements for element \"rows\":\n            | indexLocator | r:validNumber   |\n            | idLocator    | t:MY_CUSTOM_ID_ |\n            | nameLocator  | r:notEmpty      |\n            | viewButton   | f:isVisible     |\n            | viewButton   | f:isClickable   |\n        And every \"rows\" element should have the same value for element \"viewButton\"\n        And \"indexLocator\" value on the \"rows\" list is sorted in \"ascending\" order\n        And \"descendingIndex\" value on the \"rows\" list is sorted in \"descending\" order\n\n    Scenario: Validate exact tabular data by columns\n        Given I visit the \"main\" page\n        When I click the \"tabularDataLink\" element\n        Then the \"tabularData\" page is displayed\n        And there are following elements in table \"rows\":\n            | indexLocator | nameLocator          |\n            | t:1          | t:Some custom name 1 |\n            | t:2          | t:Some custom name 2 |\n            | t:3          | t:Some custom name 3 |\n            | t:4          | t:Some custom name 4 |\n        And the element \"rows\" should have an item with values:\n            | indexLocator | t:1         |\n            | indexLocator | f:isVisible |\n        And the element \"rows\" should not have an item with values:\n            | indexLocator | t:incorrect-number-value |\n\n    Scenario: Navigate to pages by using click steps\n        Given I visit the \"main\" page\n        When I click the \"valueToClick\" element\n        Then the \"tabularData\" page is displayed\n"
  },
  {
    "path": "functional-tests/features/content/validate_tabular_data_css.feature",
    "content": "Feature: Tabular data\n    As a kakunin user\n    I want validate tabular data\n\n    Scenario: Validate tabular data count\n        Given I visit the \"main\" page\n        When I click the \"a[href='/tabular-data']\" element\n        Then the \"tabularData\" page is displayed\n        And there are \"at least 1\" \"table tr\" elements\n        And there are \"above 3\" \"table tr\" elements\n        And there are \"below 5\" \"table tr\" elements\n        And there are \"within 3 5\" \"table tr\" elements\n        And there are \"equal 4\" \"table tr\" elements\n\n    Scenario: Validate tabular data count and content, also check sorting\n        Given I visit the \"main\" page\n        When I click the \"a[href='/tabular-data']\" element\n        Then the \"tabularData\" page is displayed\n        And the \"table tr\" element is visible\n        And there are \"at least 4\" following elements for element \"table tr\":\n            | .index | r:validNumber |\n        And there are \"above 3\" following elements for element \"table tr\":\n            | .index | r:validNumber |\n        And there are \"equal 4\" following elements for element \"table tr\":\n            | .index | r:validNumber |\n        And there are \"below 5\" following elements for element \"table tr\":\n            | .index | r:validNumber |\n        And there are \"within 3-5\" following elements for element \"table tr\":\n            | .index | r:validNumber |\n        And there are \"equal 4\" following elements for element \"table tr\":\n            | .index      | r:validNumber   |\n            | .id          | t:MY_CUSTOM_ID_ |\n            | .name       | r:notEmpty      |\n            | button.view | f:isVisible     |\n            | button.view | f:isClickable   |\n        And every \"table tr\" element should have the same value for element \"button.view\"\n        And \".index\" value on the \"table tr\" list is sorted in \"ascending\" order\n        And \".descending-sort\" value on the \"table tr\" list is sorted in \"descending\" order\n\n    Scenario: Validate exact tabular data by columns\n        Given I visit the \"main\" page\n        When I click the \"a[href='/tabular-data']\" element\n        Then the \"tabularData\" page is displayed\n        And there are following elements in table \"table tr\":\n            | .index | nameLocator          |\n            | t:1    | t:Some custom name 1 |\n            | t:2    | t:Some custom name 2 |\n            | t:3    | t:Some custom name 3 |\n            | t:4    | t:Some custom name 4 |\n        And the element \"table tr\" should have an item with values:\n            | .index | t:1         |\n            | .index | f:isVisible |\n        And the element \"table tr\" should not have an item with values:\n            | .index | t:incorrect-number-value |\n\n    Scenario: Navigate to pages by using click steps\n        Given I visit the \"main\" page\n        When I click the \".valueForClickStep\" element\n        Then the \"tabularData\" page is displayed\n"
  },
  {
    "path": "functional-tests/features/content/wait_for_element_dissapear.feature",
    "content": "Feature: Element visibility\n    As a kakunin user\n    I want to wait for element to disappear\n\n    Scenario: Check visibility - disappear step\n        Given I visit the \"main\" page\n        When I click the \"buttonLink\" element\n        Then the \"buttonForm\" page is displayed\n        When I click the \"disappearBtn\" element\n        Then I wait for the \"disappearBtn\" element to disappear\n\n    Scenario: Check visibility with - wait for condition step\n        Given I visit the \"main\" page\n        When I click the \"buttonLink\" element\n        Then the \"buttonForm\" page is displayed\n        When I click the \"disappearBtn\" element\n        And I wait for \"invisibilityOf\" of the \"disappearBtn\" element\n        Then the \"disappearBtn\" element is not visible\n"
  },
  {
    "path": "functional-tests/features/content/wait_for_element_dissapear_css.feature",
    "content": "Feature: Element visibility\n    As a kakunin user\n    I want to wait for element to disappear\n\n    Scenario: Check visibility - disappear step\n        Given I visit the \"main\" page\n        When I click the \"a[href='/form/disappear']\" element\n        Then the \"buttonForm\" page is displayed\n        When I click the \"#button\" element\n        Then I wait for the \"#button\" element to disappear\n\n    Scenario: Check visibility with - wait for condition step\n        Given I visit the \"main\" page\n        When I click the \"buttonLink\" element\n        Then the \"buttonForm\" page is displayed\n        When I click the \"#button\" element\n        And I wait for \"invisibilityOf\" of the \"#button\" element\n        Then the \"#button\" element is not visible\n"
  },
  {
    "path": "functional-tests/features/drag-and-drop/operations_on_elements.feature",
    "content": "Feature: Drag and drop\n    As a kakunin user\n    I want to be able to make operations on elements\n\n    Scenario: Drag element and drop on the other one\n        Given I visit the \"dragAndDrop\" page\n        When I drag \"kittens\" element and drop over \"target\" element\n        Then the \"kittensInsideTarget\" element is visible\n"
  },
  {
    "path": "functional-tests/features/drag-and-drop/operations_on_elements_css.feature",
    "content": "Feature: Drag and drop\n    As a kakunin user\n    I want to be able to make operations on elements\n\n    Scenario: Drag element and drop on the other one\n        Given I visit the \"dragAndDrop\" page\n        When I drag \"#draggable\" element and drop over \"#droppable\" element\n        Then the \".ui-state-highlight\" element is visible\n"
  },
  {
    "path": "functional-tests/features/forms/fill_and_check_form.feature",
    "content": "Feature: Forms\n    As a kakunin user\n    I want fill and check form fields\n\n    Scenario: Fill and check form fields\n        Given I visit the \"main\" page\n        When I click the \"formLink\" element\n        Then the \"simpleForm\" page is displayed\n        When I generate random \"stringWithLength:10\" as \"storedStringWithLength\"\n        And I fill the \"form\" form with:\n            | nameInput | v:storedStringWithLength |\n        Then the \"form\" form is filled with:\n            | nameInput | v:storedStringWithLength |\n        When I fill the \"form\" form with:\n            | nameInput           | d:test-dictionary:test-name |\n            | descriptionTextarea | some description            |\n            | optionCheckboxes    | Checkbox Option 2           |\n            | optionCheckboxes    | Checkbox Option 3           |\n            | optionRadios        | third-radio-option          |\n            | statusSelect        | unknown                     |\n        And I click the \"submitButton\" element\n        Then the \"simpleFormPost\" page is displayed\n        And the \"form\" form is filled with:\n            | nameInput           | d:test-dictionary:test-name |\n            | descriptionTextarea | some description            |\n            | optionCheckboxes    | Checkbox Option 2           |\n            | optionCheckboxes    | Checkbox Option 3           |\n            | optionRadios        | third-radio-option          |\n            | statusSelect        | unknown                     |\n\n    Scenario: Fill input and textarea fields and then store the values and check if the form was filled with expected data\n        Given I visit the \"main\" page\n        When I click the \"formLink\" element\n        Then the \"simpleForm\" page is displayed\n        When I generate random \"stringWithLength:6\" as \"storedStringWithLength\"\n        And I fill the \"form\" form with:\n            | nameInput | v:storedStringWithLength |\n        And I store the \"nameInput\" element text as \"storedInputValue\" variable\n        Then the \"form\" form is filled with:\n            | nameInput | v:storedStringWithLength |\n            | nameInput | v:storedInputValue       |\n        And there is element \"nameInput\" with value \"t:v:storedInputValue\"\n        And there is element \"nameInput\" with value \"t:v:storedStringWithLength\"\n        When I fill the \"form\" form with:\n            | descriptionTextarea | g:personalData:email |\n        And I store the \"descriptionTextarea\" element text as \"storedTextareaValue\" variable\n        Then the \"form\" form is filled with:\n            | descriptionTextarea | v:storedTextareaValue |\n        And there is element \"descriptionTextarea\" with value \"t:v:storedTextareaValue\"\n        And there is element \"descriptionTextarea\" with value \"r:email\"\n"
  },
  {
    "path": "functional-tests/features/forms/fill_and_check_form_css.feature",
    "content": "Feature: Forms\n    As a kakunin user\n    I want fill and check form fields\n\n    Scenario: Fill and check form fields\n        Given I visit the \"main\" page\n        When I click the \"a[href='/form/simple']\" element\n        Then the \"simpleForm\" page is displayed\n        When I generate random \"stringWithLength:10\" as \"storedStringWithLength\"\n        And I fill the \"form\" form with:\n            | nameInput | v:storedStringWithLength |\n        Then the \"form\" form is filled with:\n            | nameInput | v:storedStringWithLength |\n        When I fill the \"form\" form with:\n            | input[name=\"name\"]           | d:test-dictionary:test-name |\n            | textarea[name=\"description\"] | some description            |\n            | input[type=\"checkbox\"]       | Checkbox Option 2           |\n            | input[type=\"checkbox\"]       | Checkbox Option 3           |\n            | input[type=\"radio\"]          | third-radio-option          |\n            | select[name=\"status\"]        | unknown                     |\n        And I click the \"submitButton\" element\n        Then the \"simpleFormPost\" page is displayed\n        And the \"form\" form is filled with:\n            | input[name=\"name\"]           | d:test-dictionary:test-name |\n            | textarea[name=\"description\"] | some description            |\n            | input[type=\"checkbox\"]       | Checkbox Option 2           |\n            | input[type=\"checkbox\"]       | Checkbox Option 3           |\n            | input[type=\"radio\"]          | third-radio-option          |\n            | select[name=\"status\"]        | unknown                     |\n"
  },
  {
    "path": "functional-tests/features/forms/fill_select.feature",
    "content": "Feature: Forms\n    As a kakunin user\n    I want to check options\n\n    Scenario: Fill and check form fields\n        Given I visit the \"main\" page\n        When I click the \"formSelectLink\" element\n        Then the \"simpleSelectForm\" page is displayed\n        And there are \"personOption\" dropdown list elements with following options:\n            | Person3 |\n            | Person2 |\n            | Person1 |\n            | Person4 |\n"
  },
  {
    "path": "functional-tests/features/matchers/match_current_date.feature",
    "content": "Feature: Matchers\n    As a kakunin user\n    I want to navigate to matcher page and match current date\n\n    Scenario: I want to match current date with format\n        Given I visit the \"main\" page\n        When I click the \"matchersLink\" element\n        Then the \"matchers\" page is displayed\n        And there is element \"dateElement\" with value \"f:isVisible\"\n        And there is element \"dateMatcherText\" with value \"t:Date/Time:\"\n        And there is element \"dateElement\" with value \"f:isClickable\"\n        And there is element \"dateElement\" with value \"f:isPresent\"\n        And there is element \"dateElement\" with value \"r:notEmpty\"\n        And there is element \"dateElement\" with value \"f:currentDate:YYYY-MM-DD\"\n\n    Scenario: I want to match current date without additional parameters\n        Given I visit the \"main\" page\n        When I click the \"matchersLink\" element\n        Then the \"matchers\" page is displayed\n        And there is element \"dateElement\" with value \"f:currentDate\"\n"
  },
  {
    "path": "functional-tests/features/matchers/match_current_date_css.feature",
    "content": "Feature: Matchers\n    As a kakunin user\n    I want to navigate to matcher page and match current date\n\n    Scenario: I want to match current date with format\n        Given I visit the \"main\" page\n        When I click the \".matchers\" element\n        Then the \"matchers\" page is displayed\n        And there is element \"span.current_date\" with value \"f:isVisible\"\n        And there is element \"p.date-matcher\" with value \"t:Date/Time:\"\n        And there is element \"span.current_date\" with value \"f:isClickable\"\n        And there is element \"span.current_date\" with value \"f:isPresent\"\n        And there is element \"span.current_date\" with value \"r:notEmpty\"\n        And there is element \"span.current_date\" with value \"f:currentDate:YYYY-MM-DD\"\n\n    Scenario: I want to match current date without additional parameters\n        Given I visit the \"main\" page\n        When I click the \".matchers\" element\n        Then the \"matchers\" page is displayed\n        And there is element \"span.current_date\" with value \"f:currentDate\"\n"
  },
  {
    "path": "functional-tests/features/matchers/matchers.feature",
    "content": "Feature: Matchers\n    As a Kakunin user\n    I want to fill input and then check if the value matches the expected result\n\n    Scenario: Fill the input and check value\n        Given I visit the \"main\" page\n        When I click the \"formLink\" element\n        Then the \"simpleForm\" page is displayed\n        And I fill the \"form\" form with:\n            | nameInput | test |\n        And there is element \"nameInput\" with value \"t:test\"\n        And there is element \"nameInput\" containing \"test\" text\n        And there is no element \"nameInput\" with value \"t:hello\"\n        And there is no element \"nameInput\" containing \"hello\" text\n        And there is element \"nameInput\" matching \"isVisible\" matcher\n        And there is no element \"nameInput\" matching \"isNotVisible\" matcher\n        And there is element \"nameInput\" with \"notEmpty\" regex\n        And there is no element \"nameInput\" with \"number\" regex\n\n\n\n"
  },
  {
    "path": "functional-tests/features/matchers/matchers_css.feature",
    "content": "Feature: Matchers\n    As a Kakunin user\n    I want to fill input and then check if the value matches the expected result\n\n    Scenario: Fill the input and check value\n        Given I visit the \"main\" page\n        When I click the \"a[href='/form/simple']\" element\n        Then the \"simpleForm\" page is displayed\n        And I fill the \"form\" form with:\n            | input[name=\"name\"] | test |\n        And there is element \"input[name='name']\" with value \"t:test\"\n        And there is element \"input[name='name']\" containing \"test\" text\n        And there is no element \"input[name='name']\" with value \"t:hello\"\n        And there is no element \"input[name='name']\" containing \"hello\" text\n        And there is element \"input[name='name']\" matching \"isVisible\" matcher\n        And there is no element \"input[name='name']\" matching \"isNotVisible\" matcher\n        And there is element \"input[name='name']\" with \"notEmpty\" regex\n        And there is no element \"input[name='name']\" with \"number\" regex\n\n\n\n"
  },
  {
    "path": "functional-tests/features/navigation/navigate_to_given_page.feature",
    "content": "Feature: Navigation\n    As a kakunin user\n    I want to navigate to selected page\n\n    Scenario: Navigate by link click\n        Given I visit the \"main\" page\n        When I click the \"formLink\" element\n        Then the \"simpleForm\" page is displayed\n        And the \"form\" element is visible\n\n    Scenario: Navigate to parametrized url\n        Given I visit the \"navigationPages\" page with parameters:\n            | pageId | myPageId    |\n            | title  | myPageTitle |\n        Then there is element \"pageId\" with value \"t:myPageId\"\n        And there is element \"title\" with value \"t:myPageTitle\"\n\n    Scenario: Navigate to parametrized url with additional params\n        Given I visit the \"navigationPages\" page with parameters:\n            | pageId           | myPageId    |\n            | additionalParam1 | value1      |\n            | title            | myPageTitle |\n            | additionalParam2 | value2      |\n        Then the \"additionalParams\" page is displayed\n        # check again\n        Then I visit the \"navigationPages\" page with parameters:\n            | pageId           | myPageId    |\n            | additionalParam1 | value1      |\n            | title            | myPageTitle |\n            | additionalParam2 | value2      |\n        Then the \"additionalParams\" page is displayed\n"
  },
  {
    "path": "functional-tests/features/navigation/navigate_to_given_page_css.feature",
    "content": "Feature: Navigation\n    As a kakunin user\n    I want to navigate to selected page\n\n    Scenario: Navigate by link click\n        Given I visit the \"main\" page\n        When I click the \"a[href='/form/simple']\" element\n        Then the \"simpleForm\" page is displayed\n        And the \"form\" element is visible\n\n    Scenario: Navigate to parametrized url\n        Given I visit the \"navigationPages\" page with parameters:\n            | pageId | myPageId    |\n            | title  | myPageTitle |\n        Then there is element \"p.pageId\" with value \"t:myPageId\"\n        And there is element \"p.title\" with value \"t:myPageTitle\"\n\n"
  },
  {
    "path": "functional-tests/features/navigation/switch-between-tabs.feature",
    "content": "Feature: Navigation\n    As a kakunin user\n    I want to switch between browser tabs\n\n    Scenario: Navigate by link click\n        Given I visit the \"main\" page\n        When I click the \"matchersInNewTabLink\" element\n        And I switch to window number \"2\" of a browser\n        Then the \"matchers\" page is displayed\n        And there is element \"dateElement\" with value \"f:isVisible\"\n        When I close the current browser tab\n        Then the \"main\" page is displayed\n        When I click the \"matchersLink\" element\n        Then the \"matchers\" page is displayed\n"
  },
  {
    "path": "functional-tests/features/pages/verify_displayed_page.feature",
    "content": "Feature: Verify displayed pge\n    As a kakunin user\n    I want to make sure I am on expected page\n\n    Scenario: Verify relative page\n        Given I visit the \"main\" page\n        When I click the \"formLink\" element\n        Then the \"simpleForm\" page is displayed\n\n    Scenario: Verify absolute url page\n        Given I visit the \"main\" page\n        When I click the \"absolutePageLink\" element\n        Then the \"absolutePage\" page is displayed\n\n    Scenario: Verify external url page\n        Given I visit the \"main\" page\n        When I click the \"googleLink\" element\n        Then the \"google\" page is displayed\n"
  },
  {
    "path": "functional-tests/features/testing-api/testing_delete_request.feature",
    "content": "Feature: Test server delete request\n    As a kakunin user\n    I want to test restApi delete request\n\n    Scenario: REST get example test\n        Given I send \"delete\" request on \"deleteTestEndpoint\" endpoint\n        Then the response code should be \"200\"\n"
  },
  {
    "path": "functional-tests/features/testing-api/testing_get_response.feature",
    "content": "Feature: Test server get response\n    As a kakunin user\n    I want to test restApi get response\n\n    Scenario: REST get example test\n    Given I send \"GET\" request on \"getTestEndpoint\" endpoint\n    Then the response code should be \"200\"\n    And the response should exact match to body:\n    \"\"\"\n      {\n        \"id\": 1,\n        \"title\": \"Kaunin\",\n        \"body\": \"test\"\n       }\n    \"\"\"\n"
  },
  {
    "path": "functional-tests/features/testing-api/testing_headers_setting.feature",
    "content": "Feature: Test setting headers\n    As a kakunin user\n    I want to set the headers\n\n    Scenario: Setting http headers\n        Given I set request headers:\n        | User-Agent | Mozilla |\n        When I send \"POST\" request on \"postTestEndpoint\" endpoint with JSON body:\n        \"\"\"\n        {\n            \"title\": \"adam\",\n            \"body\": \"test\"\n        }\n        \"\"\"\n        Then the response code should be \"403\"\n"
  },
  {
    "path": "functional-tests/features/testing-api/testing_patch_request.feature",
    "content": "Feature: Test patch endpoint\n    As a kakunin user\n    I want to set test the patch endpoint\n\n    Scenario: REST patch example test\n        Given I send \"PATCH\" request on \"patchTestEndpoint\" endpoint with JSON body:\n        \"\"\"\n        {\n            \"first_name\": \"adam\"\n        }\n        \"\"\"\n        Then the response code should be \"200\"\n\n"
  },
  {
    "path": "functional-tests/features/testing-api/testing_post_form_data.feature",
    "content": "Feature: Test server post request using form data\n    As a kakunin user\n    I want to test restApi post request\n\n    Scenario: REST get example test\n        Given I send \"POST\" request on \"postFormDataEndpoint\" endpoint using form data:\n        | name | adam1 |\n        Then the response code should be \"201\"\n"
  },
  {
    "path": "functional-tests/features/testing-api/testing_post_json.feature",
    "content": "Feature: Test server post response\n    As a kakunin user\n    I want to test restApi post request\n\n    Scenario: REST post example test\n        Given I send \"POST\" request on \"postTestEndpoint\" endpoint with JSON body:\n        \"\"\"\n        {\n            \"name\": \"adam\",\n            \"title\": \"test\"\n        }\n        \"\"\"\n\n        Then the response code should be \"201\"\n        Then the response should match JSON schema:\n        \"\"\"\n        {\n            \"title\": \"Posts schema\",\n            \"type\": \"object\",\n            \"properties\": {\n                \"code\": {\n                    \"type\": \"string\"\n                },\n                \"name\": {\n                    \"type\": \"string\"\n                    },\n                \"title\": {\n                    \"type\": \"string\"\n                }\n            },\n            \"required\": [\"code\", \"name\", \"title\"]\n        }\n        \"\"\"\n"
  },
  {
    "path": "functional-tests/features/wait-for-elements/wait_for_form.feature",
    "content": "Feature: Wait for forms\n    As a kakunin user\n    I want fill and check form fields\n\n    Scenario: Fill and check form fields\n        Given I visit the \"main\" page\n        When I click the \"appearForm\" element\n        Then the \"appearSimpleForm\" page is displayed\n        When I click the \"formAppearBtn\" element\n        And I fill the \"form\" form with:\n            | nameInput           | d:test-dictionary:test-name |\n            | descriptionTextarea | some description            |\n            | optionCheckboxes    | Checkbox Option 2           |\n            | optionCheckboxes    | Checkbox Option 3           |\n            | optionRadios        | third-radio-option          |\n            | statusSelect        | unknown                     |\n        Then the \"form\" form is filled with:\n            | nameInput           | d:test-dictionary:test-name |\n            | descriptionTextarea | some description            |\n            | optionCheckboxes    | Checkbox Option 2           |\n            | optionCheckboxes    | Checkbox Option 3           |\n            | optionRadios        | third-radio-option          |\n            | statusSelect        | unknown                     |\n        When I click the \"submitButton\" element\n        Then the \"appearSimpleFormPost\" page is displayed\n"
  },
  {
    "path": "functional-tests/features/wait-for-elements/wait_for_form_css.feature",
    "content": "Feature: Wait for forms\n    As a kakunin user\n    I want fill and check form fields\n\n    Scenario: Fill and check form fields\n        Given I visit the \"main\" page\n        When I click the \".appearForm\" element\n        Then the \"appearSimpleForm\" page is displayed\n        When I click the \".colored\" element\n        And I fill the \"form\" form with:\n            | input[name=\"name\"]           | d:test-dictionary:test-name |\n            | textarea[name=\"description\"] | some description            |\n            | input[type=\"checkbox\"]       | Checkbox Option 2           |\n            | input[type=\"checkbox\"]       | Checkbox Option 3           |\n            | input[type=\"radio\"]          | third-radio-option          |\n            | select[name=\"status\"]        | unknown                     |\n        Then the \"form\" form is filled with:\n            | input[name=\"name\"]           | d:test-dictionary:test-name |\n            | textarea[name=\"description\"] | some description            |\n            | input[type=\"checkbox\"]       | Checkbox Option 2           |\n            | input[type=\"checkbox\"]       | Checkbox Option 3           |\n            | input[type=\"radio\"]          | third-radio-option          |\n            | select[name=\"status\"]        | unknown                     |\n        When I click the \"input[type='submit']\" element\n        Then the \"appearSimpleFormPost\" page is displayed\n"
  },
  {
    "path": "functional-tests/features/wait-for-elements/wait_for_table.feature",
    "content": "Feature: Wait for Tabular data\n    As a kakunin user\n    I want validate tabular data which will appear in future\n\n    Scenario: Validate tabular data count and content, also check sorting\n        Given I visit the \"main\" page\n        When I click the \"appearTable\" element\n        Then the \"appearTabularData\" page is displayed\n        When I click the \"tableAppearBtn\" element\n        Then there are \"equal 4\" following elements for element \"rows\":\n            | indexLocator | r:validNumber   |\n            | idLocator    | t:MY_CUSTOM_ID_ |\n            | nameLocator  | r:notEmpty      |\n            | viewButton   | f:isVisible     |\n            | viewButton   | f:isClickable   |\n        And every \"rows\" element should have the same value for element \"viewButton\"\n        And \"indexLocator\" value on the \"rows\" list is sorted in \"ascending\" order\n        And \"descendingIndex\" value on the \"rows\" list is sorted in \"descending\" order\n\n    Scenario: Validate tabular data count and content, also check sorting\n        Given I visit the \"main\" page\n        When I click the \"appearTable\" element\n        Then the \"appearTabularData\" page is displayed\n        When I click the \"tableAppearBtn\" element\n        And I store table \"rows\" rows as \"tableValue\" with columns:\n            | indexLocator |\n            | idLocator    |\n            | nameLocator  |\n        Then compare given JSON string with stored \"tableValue\" JSON:\n            \"\"\"\n            [\n            [\"1\",\"MY_CUSTOM_ID_1\",\"Some custom name 1\"],\n            [\"2\",\"MY_CUSTOM_ID_2\",\"Some custom name 2\"],\n            [\"3\",\"MY_CUSTOM_ID_3\",\"Some custom name 3\"],\n            [\"4\",\"MY_CUSTOM_ID_4\",\"Some custom name 4\"]\n            ]\n\n            \"\"\"\n"
  },
  {
    "path": "functional-tests/kakunin.conf.js",
    "content": "module.exports = {\n  browserWidth: 1600,\n  browserHeight: 900,\n  timeout: 60,\n  elementsVisibilityTimeout: 5,\n  waitForPageTimeout: 5,\n  downloadTimeout: 30,\n  reports: '/reports',\n  downloads: '/downloads',\n  data: '/data',\n  features: ['/features'],\n  pages: ['/pages'],\n  matchers: ['/matchers'],\n  generators: ['/generators'],\n  form_handlers: ['/form_handlers'],\n  step_definitions: ['/step_definitions'],\n  comparators: ['/comparators'],\n  dictionaries: ['/dictionaries'],\n  transformers: ['/transformers'],\n  regexes: ['/regexes'],\n  hooks: ['/hooks'],\n  clearEmailInboxBeforeTests: false,\n  clearCookiesAfterScenario: true,\n  clearLocalStorageAfterScenario: true,\n  email: null,\n  headless: true,\n  noGpu: true,\n  type: 'otherWeb',\n  baseUrl: 'http://localhost:8080',\n  apiUrl: 'http://localhost:8080/',\n  browserMob: {\n    serverPort: 8887,\n    port: 8888,\n    host: 'localhost',\n  },\n  browserstack: {\n    seleniumAddress: 'http://hub-cloud.browserstack.com/wd/hub',\n    defaultPort: 45691,\n    capabilities: {\n      'browserstack.user': '',\n      'browserstack.key': '',\n      'browserstack.local': true,\n      browserName: 'chrome',\n    }\n  },\n  accounts: {\n    someAccount: {\n      accounts: [\n        {\n          email: '',\n          password: '',\n        },\n      ],\n    },\n  },\n};\n"
  },
  {
    "path": "functional-tests/package.json",
    "content": "{\n  \"name\": \"kakunin-functional-tests\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"kakunin\": \"cross-env NODE_ENV=prod kakunin\",\n    \"start\": \"pm2 update && pm2 start www\",\n    \"stop\": \"pm2 delete www\",\n    \"test-ci\": \"npm run start && npm run kakunin -- --parallel 4 && npm run stop\",\n    \"test\": \"npm run start && npm run kakunin && npm run stop\"\n  },\n  \"author\": \"\",\n  \"dependencies\": {\n    \"body-parser\": \"1.19.0\",\n    \"cross-env\": \"7.0.3\",\n    \"express\": \"4.17.1\",\n    \"kakunin\": \"file:../\",\n    \"node-fetch\": \"2.6.1\",\n    \"nunjucks\": \"3.2.3\",\n    \"protractor\": \"7.0.0\"\n  },\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"pm2\": \"4.5.5\"\n  }\n}\n"
  },
  {
    "path": "functional-tests/pages/absolutePage.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass AbsolutePage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = 'http://localhost:8080/absolute-page';\n  }\n}\n\nmodule.exports = AbsolutePage;\n"
  },
  {
    "path": "functional-tests/pages/additionalParams.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass AdditionalParamsPage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/navigation/pages/:id/titles/:title?additionalParam1=:value1&additionalParam2=:value2';\n  }\n}\n\nmodule.exports = AdditionalParamsPage;\n"
  },
  {
    "path": "functional-tests/pages/appearSimpleForm.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass AppearSimpleForm extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/wait-for-appear/form';\n\n    this.formAppearBtn = $('.colored');\n\n    this.form = $('form');\n    this.nameInput = this.form.$('input[name=\"name\"]');\n    this.descriptionTextarea = this.form.$('textarea[name=\"description\"]');\n    this.optionCheckboxes = this.form.$$('input[type=\"checkbox\"]');\n    this.optionRadios = this.form.$$('input[type=\"radio\"]');\n    this.statusSelect = this.form.$('select[name=\"status\"]');\n\n    this.submitButton = this.form.$('input[type=\"submit\"]');\n  }\n}\n\nmodule.exports = AppearSimpleForm;\n"
  },
  {
    "path": "functional-tests/pages/appearSimpleFormPost.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass AppearSimpleFormPost extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/wait-for-appear/form/post';\n\n    this.form = $('form');\n    this.nameInput = this.form.$('input[name=\"name\"]');\n    this.descriptionTextarea = this.form.$('textarea[name=\"description\"]');\n    this.optionCheckboxes = this.form.$$('input[type=\"checkbox\"]');\n    this.optionRadios = this.form.$$('input[type=\"radio\"]');\n    this.statusSelect = this.form.$('select[name=\"status\"]');\n  }\n}\n\nmodule.exports = AppearSimpleFormPost;\n"
  },
  {
    "path": "functional-tests/pages/appearTabularData.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass AppearTabularData extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/wait-for-appear/table';\n\n    this.tableAppearBtn = $('.colored');\n    this.rows = $$('table tr');\n    this.indexLocator = $('.index');\n    this.descendingIndex = $('.descending-sort');\n    this.idLocator = $('.id');\n    this.nameLocator = $('.name');\n    this.viewButton = $('button.view');\n  }\n}\n\nmodule.exports = AppearTabularData;\n"
  },
  {
    "path": "functional-tests/pages/buttonForm.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass ButtonForm extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/form/disappear';\n\n    this.disappearBtn = $('#button');\n  }\n}\n\nmodule.exports = ButtonForm;\n"
  },
  {
    "path": "functional-tests/pages/dragAndDrop.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass DragAndDropPage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/drag-and-drop';\n\n    this.kittens = $('#draggable');\n    this.target = $('#droppable');\n    this.kittensInsideTarget = $('.ui-state-highlight');\n  }\n}\n\nmodule.exports = DragAndDropPage;\n"
  },
  {
    "path": "functional-tests/pages/google.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass GooglePage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = 'https://www.google.pl';\n  }\n}\n\nmodule.exports = GooglePage;\n"
  },
  {
    "path": "functional-tests/pages/main.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass MainPage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/';\n\n    this.linkDivs = $$('.available-examples-links');\n    this.formLink = $('a[href=\"/form/simple\"]');\n    this.formSelectLink = $('a[href=\"/form/select\"]');\n    this.absolutePageLink = $('a[href=\"/absolute-page\"]');\n    this.googleLink = $('a[href=\"https://www.google.pl\"]');\n    this.tabularDataLink = $('a[href=\"/tabular-data\"]');\n    this.buttonLink = $('a[href=\"/form/disappear\"]');\n    this.valueToClick = $('.valueForClickStep');\n    this.appearTable = $('.appearTable');\n    this.appearForm = $('.appearForm');\n    this.matchersLink = $('.matchers');\n    this.matchersInNewTabLink = $('.matchersInNewTab');\n  }\n}\n\nmodule.exports = MainPage;\n"
  },
  {
    "path": "functional-tests/pages/matchers.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass MatchersPage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/matchers';\n\n    this.dateMatcherText = $('p.date-matcher ');\n    this.dateElement = $('span.current_date ');\n  }\n}\n\nmodule.exports = MatchersPage;\n"
  },
  {
    "path": "functional-tests/pages/navigationPages.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass NavigationPagesPage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/navigation/pages/:pageId/titles/:title';\n\n    this.pageId = $('p.pageId');\n    this.title = $('p.title');\n    this.queryParam1 = $('p.queryParam1');\n    this.queryParam2 = $('p.queryParam2');\n  }\n}\n\nmodule.exports = NavigationPagesPage;\n"
  },
  {
    "path": "functional-tests/pages/simpleForm.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass SimpleForm extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/form/simple';\n\n    this.form = $('form');\n    this.nameInput = this.form.$('input[name=\"name\"]');\n    this.descriptionTextarea = this.form.$('textarea[name=\"description\"]');\n    this.optionCheckboxes = this.form.$$('input[type=\"checkbox\"]');\n    this.optionRadios = this.form.$$('input[type=\"radio\"]');\n    this.statusSelect = this.form.$('select[name=\"status\"]');\n\n    this.submitButton = this.form.$('input[type=\"submit\"]');\n  }\n}\n\nmodule.exports = SimpleForm;\n"
  },
  {
    "path": "functional-tests/pages/simpleFormPost.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass SimpleFormPost extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/form/simple/post';\n\n    this.form = $('form');\n    this.nameInput = this.form.$('input[name=\"name\"]');\n    this.descriptionTextarea = this.form.$('textarea[name=\"description\"]');\n    this.optionCheckboxes = this.form.$$('input[type=\"checkbox\"]');\n    this.optionRadios = this.form.$$('input[type=\"radio\"]');\n    this.statusSelect = this.form.$('select[name=\"status\"]');\n  }\n}\n\nmodule.exports = SimpleFormPost;\n"
  },
  {
    "path": "functional-tests/pages/simpleSelectForm.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass SimpleForm extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/form/select';\n\n    this.form = $('form');\n    this.selectPerson = $('#personlist');\n    this.personOption = this.selectPerson.$$('option');\n    this.submitButton = this.form.$('input[type=\"submit\"]');\n  }\n}\n\nmodule.exports = SimpleForm;\n"
  },
  {
    "path": "functional-tests/pages/tabularData.js",
    "content": "'use strict';\n\nconst { BasePage } = require('kakunin');\n\nclass TabularData extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/tabular-data';\n\n    this.rows = $$('table tr');\n    this.indexLocator = $('.index');\n    this.descendingIndex = $('.descending-sort');\n    this.idLocator = $('.id');\n    this.nameLocator = $('.name');\n    this.viewButton = $('button.view');\n  }\n}\n\nmodule.exports = TabularData;\n"
  },
  {
    "path": "functional-tests/regexes/index.js",
    "content": "module.exports = {\n  validNumber: '\\\\d+',\n};\n"
  },
  {
    "path": "functional-tests/step_definitions/custom_json_parser.js",
    "content": "const variableStore = require('kakunin').variableStore;\nconst fetch = require('node-fetch');\n\nconst { When } = require('kakunin');\n\nWhen(/^compare given JSON string with stored \"([^\"]*)\" JSON:$/, function(storedJsonArray, json) {\n  const removeNewLines = str => str.replace(/(\\r\\n|\\n|\\r)/gm, '');\n\n  const storedJsonString = JSON.stringify(variableStore.getVariableValue(storedJsonArray));\n  const expectedJsonString = JSON.stringify(JSON.parse(removeNewLines(json)));\n\n  if (storedJsonString === expectedJsonString) {\n    return Promise.resolve();\n  }\n\n  return Promise.reject('JSON strings are not the same!');\n});\n\nWhen(/^I store the content from \"([^\"]*)\" endpoint as \"([^\"]*)\" variable/, function(url, variableName) {\n  return fetch(url)\n    .then(res => res.json())\n    .then(data => variableStore.storeVariable(variableName, JSON.parse(data.content)));\n});\n"
  },
  {
    "path": "functional-tests/www/index.js",
    "content": "const express = require('express');\nconst nunjucks = require('nunjucks');\nconst path = require('path');\nconst app = express();\nconst { xlsxDataRouting } = require('./jsonData/xlsxData.router');\n\napp.set('views', path.join(__dirname, 'views'));\n\napp.use('/assets', express.static(path.join(__dirname, 'assets')));\n\nnunjucks.configure(app.get('views'), {\n  autoescape: true,\n  express: app,\n});\n\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\n\napp.get('/', function(req, res) {\n  res.render('index.njs');\n});\n\napp.get('/drag-and-drop', function(req, res) {\n  res.render('drag-and-drop/index.njs');\n});\n\napp.get('/tabular-data', function(req, res) {\n  res.render('table/tabular-data.njs');\n});\n\napp.get('/absolute-page', function(req, res) {\n  res.render('absolute/index.njs');\n});\n\napp.get('/form/simple', function(req, res) {\n  res.render('form/simple.njs');\n});\n\napp.get('/form/disappear', function(req, res) {\n  res.render('form/disappear.njs');\n});\n\napp.post('/form/simple/post', function(req, res) {\n  res.render('form/simple.njs', {\n    form: req.body,\n  });\n});\n\napp.get('/navigation/pages/:pageId/titles/:title', function(req, res) {\n  res.render('navigation/page.njs', {\n    pageId: req.params.pageId,\n    title: req.params.title,\n    queryParam1: req.query.queryParam1,\n    queryParam2: req.query.queryParam2\n  });\n});\n\napp.get('/wait-for-appear/table', function(req, res) {\n  res.render('wait-for-appear/table.njs');\n});\n\napp.get('/wait-for-appear/form', function(req, res) {\n  res.render('wait-for-appear/form.njs');\n});\n\napp.post('/wait-for-appear/form/post', function(req, res) {\n  res.render('wait-for-appear/form.njs', {\n    form: req.body,\n  });\n});\n\napp.get('/matchers', function(req, res) {\n  res.render('matchers/matchers.njs');\n});\n\napp.get('/form/select', function(req, res) {\n  res.render('form/select.njs');\n});\napp.post('/form/select/post', function(req, res) {\n  res.render('form/select.njs', {\n    form: req.body,\n  });\n});\n\napp.delete('/deleteTestEndpoint',function(req, res, next){\n  res.status(200);\n  return res.end();\n});\n\napp.get('/getTestEndpoint', function (req, res) {\n  res.setHeader('Content-Type', 'application/json');\n  const header = req.header('host');\n  if (header === 'localhost:8080') {\n    return res.send(JSON.stringify(\n      { id: 1,\n        title: 'Kaunin',\n        body: 'test' }\n    ));\n  }\n  res.status(403);\n  return res.end();\n});\n\napp.patch('/patchTestEndpoint', function (req, res) {\n  if(req.body.hasOwnProperty('first_name') === true) {\n    res.status(200);\n    return res.end();\n  }\n  res.status(400)\n  return res.end();\n});\n\napp.post('/postTestEndpoint', function (req, res) {\n  const name = req.body.name;\n  const title = req.body.title;\n  const header = req.header('User-Agent');\n  const object = { code: 'created', name: name, title: title };\n  if (header === 'Mozilla') {\n    res.status(403);\n    return res.end();\n  }\n  res.status(201);\n  return res.json(object);\n});\n\napp.post('/postFormDataEndpoint', function (req, res) {\n  const contentType = req.header('Content-Type');\n\n  if (contentType !== 'multipart/form-data') {\n    res.status(403);\n    return res.end();\n  }\n  res.status(201);\n  return res.end();\n});\n\napp.use('/xlsx', xlsxDataRouting());\n\napp.listen(8080, function() {\n  console.log('Example app listening on port 8080!');\n});\n"
  },
  {
    "path": "functional-tests/www/jsonData/xlsxData.router.js",
    "content": "const express = require('express');\n\nfunction xlsxDataRouting() {\n  const router = express.Router();\n\n  router.get('/data-9rows', (req, res) => {\n    res.json({\n      content:\n        '[[\"Schamberger PLC\",\"33333003158\",\"25\",\"Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"JANEK\",\"9912396963\",\"2\",\"Security Guards, Printing & Advertising, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"شركة تكامل القابضة\",\"9912396963\",\"2\",\"Contracting & Maintenance, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"شركة تكامل القابضة\",\"9912396963\",\"2\",\"Contracting & Maintenance, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"Bosco, Marks and Walker\",\"9910412435\",\"7\",\"Contracting & Maintenance, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"Rippin-Torp\",\"9912038835\",\"7\",\"Contracting & Maintenance, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"Kling-Bogan\",\"9910412335\",\"25\",\"Contracting & Maintenance, Security Guards, Printing & Advertising, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"Hane, Bartoletti and Mitchell\",\"9911038835\",\"7\",\"Contracting & Maintenance, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"Zemlak, Stiedemann and Green\",\"9912496963\",\"7\",\"Contracting & Maintenance, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"]]',\n    });\n  });\n\n  router.get('/data-9rows-part', (req, res) => {\n    res.json({\n      content:\n        '[[\"Schamberger PLC\"],[\"JANEK\"],[\"شركة تكامل القابضة\"],[\"شركة تكامل القابضة\"],[\"Bosco, Marks and Walker\"],[\"Rippin-Torp\"],[\"Kling-Bogan\"],[\"Hane, Bartoletti and Mitchell\"],[\"Zemlak, Stiedemann and Green\"]]',\n    });\n  });\n\n  router.get('/data-3rows', (req, res) => {\n    res.json({\n      content:\n        '[[\"Schamberger PLC\",\"33333003158\",\"25\",\"Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"JANEK\",\"9912396963\",\"2\",\"Security Guards, Printing & Advertising, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"],[\"شركة تكامل القابضة\",\"9912396963\",\"2\",\"Contracting & Maintenance, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"]]',\n    });\n  });\n\n  router.get('/data-3rows-part', (req, res) => {\n    res.json({\n      content:\n        '[[\"Rippin-Torp\",\"9912038835\"],[\"Kling-Bogan\",\"9910412335\"],[\"Hane, Bartoletti and Mitchell\",\"9911038835\"]]',\n    });\n  });\n\n  router.get('/data-1row', (req, res) => {\n    res.json({\n      content:\n        '[[\"Bosco, Marks and Walker\",\"9910412435\",\"7\",\"Contracting & Maintenance, Food & Consumable supply, IT, Medical Supplies and Equipment, Motors & Vehicles, Office Furniture, Office Supplies\"]]',\n    });\n  });\n\n  router.get('/data-1row-part', (req, res) => {\n    res.json({\n      content: '[[\"Bosco, Marks and Walker\",\"9910412435\"]]',\n    });\n  });\n\n  return router;\n}\n\nmodule.exports = {\n  xlsxDataRouting,\n};\n"
  },
  {
    "path": "functional-tests/www/views/absolute/index.njs",
    "content": "{% extends 'layout/default.njs' %}\n\n{% block content %}\n  <p>Absolute page</p>\n{% endblock %}\n"
  },
  {
    "path": "functional-tests/www/views/drag-and-drop/index.njs",
    "content": "{% extends 'layout/default.njs' %}\n\n{% block content %}\n  <link rel=\"stylesheet\" href=\"//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css\">\n  <style>\n    #draggable { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 10px 10px 10px 0; }\n    #droppable { width: 150px; height: 150px; padding: 0.5em; float: left; margin: 10px; }\n  </style>\n  <script src=\"https://code.jquery.com/jquery-1.12.4.js\"></script>\n  <script src=\"https://code.jquery.com/ui/1.12.1/jquery-ui.js\"></script>\n  <script>\n    $( function() {\n      $( \"#draggable\" ).draggable();\n      $( \"#droppable\" ).droppable({\n        drop: function( event, ui ) {\n          $( this )\n            .addClass( \"ui-state-highlight\" );\n        }\n      });\n    } );\n  </script>\n  <div id=\"droppable\"></div>\n  <img id=\"draggable\" src=\"/assets/kittens.jpg\" width=\"336\" height=\"69\">\n{% endblock %}\n"
  },
  {
    "path": "functional-tests/www/views/form/disappear.njs",
    "content": "{% block content %}\n<button id=\"button\">Click me.</button>\n\n<script>\ndocument.getElementById(\"button\").onclick = function() {myFunction()};\n\nfunction myFunction() {\n  setTimeout(function(){\n    document.getElementById(\"button\").remove();\n  }, 2000)\n}\n</script>\n\n{% endblock %}\n"
  },
  {
    "path": "functional-tests/www/views/form/select.njs",
    "content": "{% extends 'layout/default.njs' %}\n\n{% block content %}\n  <form method=\"post\" action=\"/form/select/post\">\n    <select name=\"list\" id=\"personlist\">\n        <option value=\"1\">Person1</option>\n        <option value=\"2\">Person2</option>\n        <option value=\"3\">Person3</option>\n        <option value=\"4\">Person4</option>\n     </select>\n    <input type=\"submit\" value=\"Send\"/>\n  </form>\n{% endblock %}\n"
  },
  {
    "path": "functional-tests/www/views/form/simple.njs",
    "content": "{% extends 'layout/default.njs' %}\n\n{% block content %}\n  <form method=\"post\" action=\"/form/simple/post\">\n    <label for=\"name\">\n      Name\n      <input type=\"text\" name=\"name\" id=\"name\" value=\"{{ form.name | default('') }}\"/>\n    </label>\n\n    <label for=\"description\">\n      Description\n      <textarea name=\"description\" id=\"description\">{{ form.description | default('') }}</textarea>\n    </label>\n\n    <label for=\"checkbox-option-1\">\n      Checkbox Option 1\n      <input type=\"checkbox\" name=\"checkboxes\" id=\"checkbox-option-1\" value=\"first-checkbox-option\" {{ 'checked' if form.checkboxes and form.checkboxes.indexOf('first-checkbox-option') >= 0 }}/>\n    </label>\n\n    <label for=\"checkbox-option-2\">\n      Checkbox Option 2\n      <input type=\"checkbox\" name=\"checkboxes\" id=\"checkbox-option-2\" value=\"second-checkbox-option\" {{ 'checked' if form.checkboxes and form.checkboxes.indexOf('second-checkbox-option') >= 0 }}/>\n    </label>\n\n    <label for=\"checkbox-option-3\">\n      Checkbox Option 3\n      <input type=\"checkbox\" name=\"checkboxes\" id=\"checkbox-option-3\" value=\"third-checkbox-option\" {{ 'checked' if form.checkboxes and form.checkboxes.indexOf('third-checkbox-option') >= 0 }}/>\n    </label>\n\n    <label for=\"radio-option-1\">\n      Radio Option 1\n      <input type=\"radio\" name=\"radios\" id=\"radio-option-1\" value=\"first-radio-option\" {{ 'checked' if form.radios === 'first-radio-option' }}/>\n    </label>\n\n    <label for=\"radio-option-2\">\n      Radio Option 2\n      <input type=\"radio\" name=\"radios\" id=\"radio-option-2\" value=\"second-radio-option\" {{ 'checked' if form.radios === 'second-radio-option' }}/>\n    </label>\n\n    <label for=\"radio-option-3\">\n      Radio Option 3\n      <input type=\"radio\" name=\"radios\" id=\"radio-option-3\" value=\"third-radio-option\" {{ 'checked' if form.radios === 'third-radio-option' }}/>\n    </label>\n\n    <label for=\"status\">\n      Status\n      <select name=\"status\">\n        <option value>Select option</option>\n        <option value=\"active\" {{ 'selected' if form.status === 'active'  }}>Active</option>\n        <option value=\"inactive\" {{ 'selected' if form.status === 'inactive'  }}>Inactive</option>\n        <option value=\"unknown\" {{ 'selected' if form.status === 'unknown'  }}>Unknown</option>\n      </select>\n    </label>\n\n    <input type=\"submit\" value=\"Send\"/>\n  </form>\n{% endblock %}\n"
  },
  {
    "path": "functional-tests/www/views/index.njs",
    "content": "{% extends 'layout/default.njs' %}\n\n{% block content %}\n  <div class=\"available-examples-links\">\n    <a name=\"linkPage\" href=\"/form/simple\">Drag and drop example</a><br/>\n    <a name=\"linkPage\" href=\"/form/simple\">Simple form example</a><br/>\n    <a name=\"linkPage\" href=\"/absolute-page\">Absolute page</a><br/>\n    <a name=\"linkPage\" href=\"https://www.google.pl\">Google page</a><br/>\n    <a name=\"linkPage\" class=\"valueForClickStep\" href=\"/tabular-data\">Simple table example</a><br/>\n    <a name=\"linkPage\" class=\"valueForClickStep\" href=\"/form/disappear\"> Simple button disappear</a><br/>\n    <a name=\"linkPage\" class=\"appearTable\" href=\"/wait-for-appear/table\"> Simple wait for table</a><br/>\n    <a name=\"linkPage\" class=\"appearForm\" href=\"/wait-for-appear/form\"> Simple wait for form</a><br/>\n    <a name=\"linkPage\" class=\"matchers\" href=\"/matchers\">Simple matchers</a><br/>\n    <a name=\"linkPage\" class=\"matchersInNewTab\" target=\"_blank\" href=\"/matchers\">Matchers in a new tab</a><br/>\n    <a name=\"linkPage\" href=\"/form/select\">Simple select example</a><br/>\n  </div>\n{% endblock %}\n"
  },
  {
    "path": "functional-tests/www/views/layout/default.njs",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\">\n    <title>Example app</title>\n  </head>\n  <body style=\"background: url('./assets/kittens.jpg')\">\n    {% block content %}\n    {% endblock %}\n  </body>\n</html>\n"
  },
  {
    "path": "functional-tests/www/views/matchers/matchers.njs",
    "content": "{% block content %}\n\n  <style>\n\n    .colored {\n      display: block;\n      background-color: #00b8d4;\n      outline: none;\n    }\n  </style>\n\n  <p class=\"date-matcher\">Date/Time: <span class=\"current_date colored\"id=\"datetime\"></span></p>\n\n\n\n{% endblock %}\n{% block javascript %}\n  <script>\n    window.onload = function () {\n      let dt = new Date().toISOString().slice(0, 10);\n      document.getElementById('datetime').innerHTML = dt.toLocaleString();\n    };\n  </script>\n{% endblock javascript %}\n"
  },
  {
    "path": "functional-tests/www/views/navigation/page.njs",
    "content": "{% extends 'layout/default.njs' %}\n\n{% block content %}\n  <p class=\"pageId\">{{ pageId }}</p>\n  <p class=\"title\">{{ title }}</p>\n  <p class=\"queryParam1\">{{ queryParam1 }}</p>\n  <p class=\"queryParam2\">{{ queryParam2 }}</p>\n{% endblock %}\n"
  },
  {
    "path": "functional-tests/www/views/table/tabular-data.njs",
    "content": "{% extends 'layout/default.njs' %}\n\n{% block content %}\n  <table>\n    <tr>\n      <td class=\"index\">1</td>\n      <td class=\"descending-sort\">4</td>\n      <td class=\"id\">MY_CUSTOM_ID_1</td>\n      <td class=\"name\">Some custom name 1</td>\n      <td class=\"options\">\n        <button class=\"view\">View</button>\n      </td>\n    </tr>\n    <tr>\n      <td class=\"index\">2</td>\n      <td class=\"descending-sort\">3</td>\n      <td class=\"id\">MY_CUSTOM_ID_2</td>\n      <td class=\"name\">Some custom name 2</td>\n      <td class=\"options\">\n        <button class=\"view\">View</button>\n      </td>\n    </tr>\n    <tr>\n      <td class=\"index\">3</td>\n      <td class=\"descending-sort\">2</td>\n      <td class=\"id\">MY_CUSTOM_ID_3</td>\n      <td class=\"name\">Some custom name 3</td>\n      <td class=\"options\">\n        <button class=\"view\">View</button>\n      </td>\n    </tr>\n    <tr>\n      <td class=\"index\">4</td>\n      <td class=\"descending-sort\">1</td>\n      <td class=\"id\">MY_CUSTOM_ID_4</td>\n      <td class=\"name\">Some custom name 4</td>\n      <td class=\"options\">\n        <button class=\"view\">View</button>\n      </td>\n    </tr>\n  </table>\n{% endblock %}\n"
  },
  {
    "path": "functional-tests/www/views/wait-for-appear/form.njs",
    "content": "{% block content %}\n\n  <style>\n    .hidden {\n      display: none;\n    }\n\n    .colored {\n      display: block;\n      background-color: #00b8d4;\n      outline: none;\n    }\n  </style>\n\n  <button id=\"hiddenContent\" class=\"hidden\" onclick=\"myFunction();\">Render Form</button>\n\n  <hr>\n  <div id=\"hiddenForm\" class=\"hidden\">\n    <form method=\"post\" action=\"/wait-for-appear/form/post\">\n      <label for=\"name\">\n        Name\n        <input type=\"text\" name=\"name\" id=\"name\" value=\"{{ form.name | default('') }}\"/>\n      </label>\n\n      <label for=\"description\">\n        Description\n        <textarea name=\"description\" id=\"description\">{{ form.description | default('') }}</textarea>\n      </label>\n\n      <label for=\"checkbox-option-1\">\n        Checkbox Option 1\n        <input type=\"checkbox\" name=\"checkboxes\" id=\"checkbox-option-1\"\n               value=\"first-checkbox-option\" {{ 'checked' if form.checkboxes and form.checkboxes.indexOf('first-checkbox-option') >= 0 }}/>\n      </label>\n\n      <label for=\"checkbox-option-2\">\n        Checkbox Option 2\n        <input type=\"checkbox\" name=\"checkboxes\" id=\"checkbox-option-2\"\n               value=\"second-checkbox-option\" {{ 'checked' if form.checkboxes and form.checkboxes.indexOf('second-checkbox-option') >= 0 }}/>\n      </label>\n\n      <label for=\"checkbox-option-3\">\n        Checkbox Option 3\n        <input type=\"checkbox\" name=\"checkboxes\" id=\"checkbox-option-3\"\n               value=\"third-checkbox-option\" {{ 'checked' if form.checkboxes and form.checkboxes.indexOf('third-checkbox-option') >= 0 }}/>\n      </label>\n\n      <label for=\"radio-option-1\">\n        Radio Option 1\n        <input type=\"radio\" name=\"radios\" id=\"radio-option-1\"\n               value=\"first-radio-option\" {{ 'checked' if form.radios === 'first-radio-option' }}/>\n      </label>\n\n      <label for=\"radio-option-2\">\n        Radio Option 2\n        <input type=\"radio\" name=\"radios\" id=\"radio-option-2\"\n               value=\"second-radio-option\" {{ 'checked' if form.radios === 'second-radio-option' }}/>\n      </label>\n\n      <label for=\"radio-option-3\">\n        Radio Option 3\n        <input type=\"radio\" name=\"radios\" id=\"radio-option-3\"\n               value=\"third-radio-option\" {{ 'checked' if form.radios === 'third-radio-option' }}/>\n      </label>\n\n      <label for=\"status\">\n        Status\n        <select name=\"status\">\n          <option value>Select option</option>\n          <option value=\"active\" {{ 'selected' if form.status === 'active' }}>Active</option>\n          <option value=\"inactive\" {{ 'selected' if form.status === 'inactive' }}>Inactive</option>\n          <option value=\"unknown\" {{ 'selected' if form.status === 'unknown' }}>Unknown</option>\n        </select>\n      </label>\n\n      <input type=\"submit\" value=\"Send\"/>\n    </form>\n  </div>\n\n\n{% endblock %}\n{% block javascript %}\n  <script>\n\n    window.onload = function() {\n      setTimeout(function() {\n        document.getElementById('hiddenContent').className = 'colored';\n\n      }, 4000);\n    };\n\n    function myFunction() {\n      setTimeout(function() {\n        document.getElementById('hiddenForm').removeAttribute('class');\n\n      }, 4000);\n    }\n  </script>\n{% endblock javascript %}\n"
  },
  {
    "path": "functional-tests/www/views/wait-for-appear/table.njs",
    "content": "{% block content %}\n\n  <style>\n    .hidden {\n      display: none;\n    }\n\n    .colored {\n      display: block;\n      background-color: #00b8d4;\n      outline: none;\n    }\n  </style>\n\n  <button id=\"hiddenContent\" class=\"hidden\" onclick=\"myFunction()\">Render Table</button>\n\n  <hr>\n  <table id=\"hiddenTable\" class=\"hidden\">\n    <tr>\n      <td class=\"index\">1</td>\n      <td class=\"descending-sort\">4</td>\n      <td class=\"id\">MY_CUSTOM_ID_1</td>\n      <td class=\"name\">Some custom name 1</td>\n      <td class=\"options\">\n        <button class=\"view\">View</button>\n      </td>\n    </tr>\n    <tr>\n      <td class=\"index\">2</td>\n      <td class=\"descending-sort\">3</td>\n      <td class=\"id\">MY_CUSTOM_ID_2</td>\n      <td class=\"name\">Some custom name 2</td>\n      <td class=\"options\">\n        <button class=\"view\">View</button>\n      </td>\n    </tr>\n    <tr>\n      <td class=\"index\">3</td>\n      <td class=\"descending-sort\">2</td>\n      <td class=\"id\">MY_CUSTOM_ID_3</td>\n      <td class=\"name\">Some custom name 3</td>\n      <td class=\"options\">\n        <button class=\"view\">View</button>\n      </td>\n    </tr>\n    <tr>\n      <td class=\"index\">4</td>\n      <td class=\"descending-sort\">1</td>\n      <td class=\"id\">MY_CUSTOM_ID_4</td>\n      <td class=\"name\">Some custom name 4</td>\n      <td class=\"options\">\n        <button class=\"view\">View</button>\n      </td>\n    </tr>\n  </table>\n\n\n{% endblock %}\n{%  block javascript %}\n  <script>\n\n    window.onload = function(){\n      setTimeout(function() {\n        document.getElementById('hiddenContent').className = 'colored';\n\n      }, 4000)\n    }\n\n    function myFunction() {\n      setTimeout(function() {\n        document.getElementById('hiddenTable').removeAttribute(\"class\")\n\n      }, 4000);\n    }\n  </script>\n{% endblock javascript %}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"kakunin\",\n  \"version\": \"3.0.3\",\n  \"description\": \"End-to-end testing framework\",\n  \"homepage\": \"https://thesoftwarehouse.github.io/Kakunin/\",\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/TheSoftwareHouse/Kakunin.git\"\n  },\n  \"author\": {\n    \"name\": \"The Software House\",\n    \"url\": \"http://tsh.io\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Adam Polak\"\n    },\n    {\n      \"name\": \"Mariusz Richtscheid\"\n    },\n    {\n      \"name\": \"Tomasz Górski\"\n    },\n    {\n      \"name\": \"Jakub Paluch\"\n    },\n    {\n      \"name\": \"Szymon Stanisz\"\n    },\n    {\n      \"name\": \"Wojciech Wójcik\"\n    },\n    {\n      \"name\": \"Józef Szymala\"\n    },\n    {\n      \"name\": \"Adam Nowrot\"\n    }\n  ],\n  \"bin\": {\n    \"kakunin\": \"./dist/cli.js\"\n  },\n  \"main\": \"./dist/index\",\n  \"scripts\": {\n    \"units\": \"cross-env jest  --setupFiles ./src/tests/init.ts --no-cache\",\n    \"functional\": \"npm run build && cd functional-tests && rm -rf package-lock.json && rm -rf node_modules && npm i && npm run test\",\n    \"test\": \"npm run units && npm run functional\",\n    \"test-ci\": \"npm run units && npm run build && cd functional-tests && npm i && npm run test-ci\",\n    \"lint\": \"tslint -c tslint.json 'src/**/*.ts'\",\n    \"lint-fix\": \"tslint -c tslint.json 'src/**/*.ts' --fix\",\n    \"prettier\": \"prettier --write 'src/**/*.ts'\",\n    \"type-check\": \"tsc --noEmit\",\n    \"build\": \"tsc\",\n    \"prepublishOnly\": \"npm run build && npm run test\"\n  },\n  \"engines\": {\n    \"node\": \">=7.7.3\",\n    \"npm\": \">=4.1.2\"\n  },\n  \"devDependencies\": {\n    \"@types/extend\": \"3.0.1\",\n    \"@types/faker\": \"5.1.7\",\n    \"@types/glob\": \"7.1.3\",\n    \"@types/inquirer\": \"7.3.1\",\n    \"@types/jest\": \"26.0.22\",\n    \"@types/lodash\": \"4.14.168\",\n    \"@types/minimist\": \"1.2.1\",\n    \"@types/mkdirp\": \"1.0.1\",\n    \"@types/moment\": \"2.13.0\",\n    \"@types/node\": \"14.14.37\",\n    \"@types/node-fetch\": \"2.5.8\",\n    \"@types/protractor\": \"4.0.0\",\n    \"@types/shelljs\": \"0.8.8\",\n    \"@types/cucumber\": \"6.0.1\",\n    \"fetch-mock\": \"9.11.0\",\n    \"husky\": \"6.0.0\",\n    \"lint-staged\": \"10.5.4\",\n    \"prettier\": \"2.2.1\",\n    \"ts-jest\": \"26.5.4\",\n    \"tslint\": \"6.1.3\",\n    \"tslint-config-prettier\": \"1.18.0\",\n    \"tslint-sonarts\": \"1.9.0\",\n    \"typescript\": \"4.2.3\"\n  },\n  \"dependencies\": {\n    \"ajv\": \"8.0.1\",\n    \"browsermob-proxy\": \"1.0.10\",\n    \"browserstack-local\": \"1.4.8\",\n    \"chai\": \"4.3.4\",\n    \"chalk\": \"4.1.0\",\n    \"child_process\": \"1.0.2\",\n    \"cross-env\": \"7.0.3\",\n    \"cucumber\": \"6.0.5\",\n    \"extend\": \"3.0.2\",\n    \"faker\": \"5.5.1\",\n    \"glob\": \"7.1.6\",\n    \"inquirer\": \"8.0.0\",\n    \"jasmine\": \"3.7.0\",\n    \"jasmine-reporters\": \"2.4.0\",\n    \"jasmine-spec-reporter\": \"6.0.0\",\n    \"jest\": \"26.6.3\",\n    \"lodash\": \"4.17.21\",\n    \"minimist\": \"1.2.5\",\n    \"mkdirp\": \"1.0.4\",\n    \"moment\": \"2.29.1\",\n    \"node-env-file\": \"0.1.8\",\n    \"node-fetch\": \"2.6.1\",\n    \"node-xlsx\": \"0.16.1\",\n    \"path\": \"0.12.7\",\n    \"protractor\": \"7.0.0\",\n    \"protractor-cucumber-framework\": \"8.0.1\",\n    \"protractor-multiple-cucumber-html-reporter-plugin\": \"1.8.1\",\n    \"shelljs\": \"0.8.4\",\n    \"sugar-date\": \"2.0.6\",\n    \"webdriver-manager\": \"12.1.8\"\n  },\n  \"jest\": {\n    \"collectCoverageFrom\": [\n      \"src/**/*.ts\",\n      \"!src/**/index.ts\",\n      \"!src/**/*.d.ts\"\n    ],\n    \"transform\": {\n      \"^.+\\\\.(t|j)sx?$\": \"ts-jest\"\n    },\n    \"testRegex\": \"(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.(jsx?|tsx?)$\",\n    \"moduleFileExtensions\": [\n      \"ts\",\n      \"tsx\",\n      \"js\",\n      \"jsx\",\n      \"json\",\n      \"node\"\n    ],\n    \"globals\": {\n      \"ts-jest\": {\n        \"tsConfig\": \"tsconfig.test.json\"\n      }\n    }\n  },\n  \"lint-staged\": {\n    \"src/**/*.ts\": [\n      \"prettier --write\",\n      \"npm run lint\",\n      \"git add\"\n    ]\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\"\n    }\n  }\n}\n"
  },
  {
    "path": "readme.md",
    "content": "<p align=\"center\">\n  <img src=\"/data/kakunin_logo.png\" alt=\"kakunin.png\" width=\"550\"/>\n</p>\n\n<p align=\"center\">\n  <img src=\"/data/travis.png\" alt=\"travis.png\" width=\"25\" />\n   Current travis build:\n  <a href=\"https://travis-ci.org/TheSoftwareHouse/Kakunin\"><img src=\"https://travis-ci.org/TheSoftwareHouse/Kakunin.svg?branch=master\" alt=\"build status\" height=\"18\"></a>\n  &emsp;\n  <img src=\"/data/npm.png\" alt=\"npm.png\" width=\"25\"/> \n  Current npm version:\n  <a href=\"https://badge.fury.io/js/kakunin\"><img src=\"https://badge.fury.io/js/kakunin.svg\" alt=\"npm version\" height=\"18\"></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#key-features\">Key Features</a> •\n  <a href=\"#documentation\">Documentation</a> •\n  <a href=\"#contributing\">Contributing</a> •\n  <a href=\"#issues\">Issues</a> •\n  <a href=\"#you-may-also-like-our-other-projects\">Related</a> •\n  <a href=\"#about-us\">About us</a>\n</p>\n\n<p align=\"center\">\n  <img src=\"/data/pageObjectFeature.gif\" alt=\"pageObjectFeature.gif\"/>\n</p>\n\n<h1>\n</h1>\n\n### **Automated testing framework**\n\nKakunin is a Protractor extension created by The Software House sp. z o.o. and Takamol Holding. It allows you to write e2e test scenarios with a help of Gherkin language and JavaScript for all kind of applications - Angular, React and others.\n\n---\n\n### **Key Features:**\n\n1. E2E testing\n2. Performance testing\n3. Parallel testing\n4. Cross browser testing\n5. Reports\n\n---\n\n### **Documentation:**\n\nYou can find documentation on the **[official page](https://kakunin.io)**.\n\n---\n\n### **Contributing:**\n\nFeel free to contribute to this project! Just fork the code, make any updated and let us know!\n\n---\n\n### **Issues:**\n\nIf you notice any issues while using, let as know on **[github](https://github.com/TheSoftwareHouse/Kakunin/issues)**.\nSecurity issues, please sent on <a href=\"mailto:security.opensource@tsh.io\"><b>email</b></a>\n\n---\n\n### **You may also like our other projects:**\n\n- **[Babelsheet-js](https://github.com/TheSoftwareHouse/babelsheet-js)**\n- **[Fogger](https://github.com/TheSoftwareHouse/fogger)**\n\n---\n\n### **About us:**\n\n<p align=\"center\">\n  <a href=\"https://tsh.io/pl\"><b>The Software House</b></a>\n  &emsp;\n  <img src=\"/data/tsh.png\" alt=\"tsh.png\" width=\"50\" />\n</p>\n"
  },
  {
    "path": "src/cli.ts",
    "content": "#!/usr/bin/env node\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport * as childProcess from 'child_process';\nimport * as envfile from 'node-env-file';\nimport { createTagsCLIArgument, filterCLIArguments, getConfigPath, isInitCommand } from './core/cli/cli.helper';\nimport initializer from './core/cli/initializer';\nconst commandArgs = require('minimist')(process.argv.slice(2));\n\nenvfile(process.cwd() + '/.env', { raise: false, overwrite: false });\n\nif (isInitCommand(process.argv)) {\n  (async () => {\n    await initializer.initConfig(commandArgs);\n    await initializer.generateProjectStructure();\n  })();\n} else {\n  const optionsToFilter = ['config', 'projectPath', 'disableChecks', 'tags'];\n\n  const argv = [\n    './node_modules/kakunin/dist/protractor.conf.js',\n    `--config=${getConfigPath('kakunin.conf.js', commandArgs.config, process.cwd())}`,\n    `--projectPath=${process.cwd()}`,\n    '--disableChecks',\n    ...createTagsCLIArgument(commandArgs),\n    ...filterCLIArguments(optionsToFilter)(commandArgs),\n  ];\n\n  const protractorExecutable = os.platform() === 'win32' ? 'protractor.cmd' : 'protractor';\n\n  if (\n    !fs.existsSync(\n      path.join(\n        process.cwd(),\n        'node_modules',\n        'protractor',\n        'node_modules',\n        'webdriver-manager',\n        'selenium',\n        'update-config.json'\n      )\n    )\n  ) {\n    childProcess.execSync(\n      path.join(process.cwd(), 'node_modules', '.bin', 'webdriver-manager update --ie --versions.standalone=3.14.0')\n    );\n  }\n\n  childProcess\n    .spawn(path.join('node_modules', '.bin', protractorExecutable), argv, {\n      stdio: 'inherit',\n      cwd: process.cwd(),\n    })\n    .once('exit', code => {\n      console.log('Protractor has finished');\n      process.exit(code);\n    });\n}\n"
  },
  {
    "path": "src/comparators/comparator/date.comparator.spec.ts",
    "content": "import { DateComparator, supportedFormats } from './date.comparator';\n\ndescribe('Date comparator', () => {\n  it('is satisfied by dates', () => {\n    const dates = ['20-12-2017', '20-12-17', '20/12/2017', '20/12/17'];\n\n    expect(DateComparator.isSatisfiedBy(dates)).toEqual(true);\n  });\n\n  it('supports only specified date formats', () => {\n    const dates = ['12-20-2017', '20/20/17', 'not-a-date', 31337];\n\n    dates.forEach(date => expect(DateComparator.isSatisfiedBy([date])).toEqual(false));\n  });\n\n  it('is pluggable', () => {\n    supportedFormats.push('MM-DD-YYYY');\n\n    expect(DateComparator.isSatisfiedBy(['12-20-2017'])).toEqual(true);\n  });\n\n  it('it returns resolved promise if dates are in ascending order', done => {\n    const ascendingDates = ['10-12-2017', '11-12-2017', '01-01-2018'];\n\n    DateComparator.compare(ascendingDates, 'ascending').then(() => done());\n  });\n\n  it('it returns resolved promise if dates are in descending order', done => {\n    const descendingDates = ['10-12-2019', '11-12-2018', '01-01-2017'];\n\n    DateComparator.compare(descendingDates, 'descending').then(() => done());\n  });\n\n  it('it returns rejected promise if dates are not in ascending order for ascending order expectation', done => {\n    const descendingDates = ['10-12-2019', '11-12-2018', '01-01-2017'];\n\n    DateComparator.compare(descendingDates, 'ascending').catch(() => done());\n  });\n\n  it('it returns rejected promise if dates are not in descending order for descending order expectation', done => {\n    const ascendingDates = ['10-12-2017', '11-12-2017', '01-01-2018'];\n\n    DateComparator.compare(ascendingDates, 'descending').catch(() => done());\n  });\n});\n"
  },
  {
    "path": "src/comparators/comparator/date.comparator.ts",
    "content": "import * as moment from 'moment';\nimport { Comparator } from '../comparator.interface';\n\nexport const supportedFormats = ['DD-MM-YYYY', 'DD-MM-YY', 'DD/MM/YYYY', 'DD/MM/YY'];\n\nconst isValidDate = date => {\n  for (const format of supportedFormats) {\n    if (moment(date, format).isValid()) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\nexport const DateComparator: Comparator = {\n  isSatisfiedBy: values => {\n    for (const date of values) {\n      const found = isValidDate(date);\n\n      if (!found) {\n        return false;\n      }\n    }\n    return true;\n  },\n\n  compare: (values, order) => {\n    for (let i = 1; i < values.length; i++) {\n      const datePrevious = values[i - 1];\n      const date = values[i];\n      const foundPrevious = moment(\n        datePrevious,\n        supportedFormats.find(format => moment(datePrevious, format).isValid())\n      );\n      const found = moment(date, supportedFormats.find(format => moment(date, format).isValid()));\n\n      const previousTimestamp = foundPrevious.unix();\n      const currentTimestamp = found.unix();\n\n      if (order === 'ascending') {\n        if (currentTimestamp < previousTimestamp) {\n          return Promise.reject(`Date ${foundPrevious[1]} should be before ${found[1]}.`);\n        }\n      } else if (currentTimestamp > previousTimestamp) {\n        return Promise.reject(`Date ${found[1]} should be after ${foundPrevious[1]}.`);\n      }\n    }\n    return Promise.resolve();\n  },\n};\n"
  },
  {
    "path": "src/comparators/comparator/index.ts",
    "content": "export * from './date.comparator';\nexport * from './number.comparator';\n"
  },
  {
    "path": "src/comparators/comparator/number.comparator.spec.ts",
    "content": "import { NumberComparator } from './number.comparator';\n\ndescribe('Number comparator', () => {\n  it('is satisfied by numbers', () => {\n    const numbers = ['10', '10.09', '0.3'];\n\n    expect(NumberComparator.isSatisfiedBy(numbers)).toEqual(true);\n  });\n\n  it('supports only specified number records', () => {\n    const numbers = ['string', '12-12-2017'];\n\n    numbers.forEach(number => expect(NumberComparator.isSatisfiedBy([number])).toEqual(false));\n  });\n\n  it('it returns resolved promise if numbers are in ascending order', done => {\n    const ascendingNumbers = ['0.25', '10', '102', '105', '125.32'];\n\n    NumberComparator.compare(ascendingNumbers, 'ascending').then(() => done());\n  });\n\n  it('it returns resolved promise if numbers are in descending order', done => {\n    const descendingNumbers = ['102', '100', '10.03'];\n\n    NumberComparator.compare(descendingNumbers, 'descending').then(() => done());\n  });\n\n  it('it returns rejected promise if numbers are not in ascending order for ascending order expectation', done => {\n    const descendingNumbers = [331, 223.03, '123', '11.04', 0.1];\n\n    NumberComparator.compare(descendingNumbers, 'ascending').catch(() => done());\n  });\n\n  it('it returns rejected promise if numbers are not in descending order for descending order expectation', done => {\n    const ascendingNumbers = ['312', '324.43', '1323.320', 1321, 0.5];\n\n    NumberComparator.compare(ascendingNumbers, 'descending').catch(() => done());\n  });\n\n  it('it returns rejected promise if numbers are in incorrect format', done => {\n    const containsIncorrectNumber = ['10', '999,32', '8dsa', '20/12/2018'];\n\n    NumberComparator.compare(containsIncorrectNumber, 'ascending').catch(() => done());\n  });\n});\n"
  },
  {
    "path": "src/comparators/comparator/number.comparator.ts",
    "content": "import { Comparator } from '../comparator.interface';\n\nexport const NumberComparator: Comparator = {\n  isSatisfiedBy: values => {\n    for (const value of values) {\n      const numberValue = Number(value);\n      if (Number.isNaN(numberValue)) {\n        return false;\n      }\n    }\n    return true;\n  },\n\n  compare: (values, order) => {\n    for (let i = 1; i < values.length; i++) {\n      const previousValue = Number(values[i - 1]);\n      const currentValue = Number(values[i]);\n\n      if (Number.isNaN(previousValue) || Number.isNaN(currentValue)) {\n        return Promise.reject(`${values[i - 1]} and ${values[i]} cannot be NaN after conversion to Number`);\n      }\n\n      if (order === 'ascending') {\n        if (previousValue > currentValue) {\n          return Promise.reject(`${previousValue} should be lower than ${currentValue}`);\n        }\n      } else if (previousValue < currentValue) {\n        return Promise.reject(`${previousValue} should be higher than ${currentValue}`);\n      }\n    }\n    return Promise.resolve();\n  },\n};\n"
  },
  {
    "path": "src/comparators/comparator.interface.ts",
    "content": "export interface Comparator {\n  isSatisfiedBy(value: any[]): boolean;\n  compare(values: any[], order: string): Promise<string | void>;\n}\n"
  },
  {
    "path": "src/comparators/comparators.spec.ts",
    "content": "import { create } from './comparators';\n\nconst comparators = create();\n\ndescribe('Comparators', () => {\n  it('throws an error when no comparator was found', () => {\n    const values = ['unspecified-value', 'other-value'];\n    expect(() => comparators.compare(values, 'ascending')).toThrow(`Could not find comparator for ${values}.`);\n  });\n\n  it('compares values using comparator that can handle given set of values', done => {\n    const numbers = [2, 3, 4];\n    comparators.compare(numbers, 'ascending').then(() => done());\n  });\n\n  it('add new comparator', done => {\n    const myComparator = {\n      isSatisfiedBy: values => {\n        for (let i = 0; i < values.length; i++) {\n          if (values[i] !== 'foo' && values[i] !== 'bar') {\n            return false;\n          }\n        }\n\n        return true;\n      },\n      compare: (values, order) => {\n        for (let i = 1; i < values.length; i++) {\n          const previousValue = values[i - 1];\n          const currentValue = values[i];\n\n          if (previousValue === currentValue) {\n            return Promise.reject('Wrong order');\n          }\n        }\n\n        return Promise.resolve('Foo bar!');\n      },\n    };\n\n    comparators.addComparator(myComparator);\n\n    const myValues = ['foo', 'bar', 'foo', 'bar', 'foo', 'bar'];\n\n    comparators.compare(myValues, 'any').then(value => {\n      expect(value).toEqual('Foo bar!');\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/comparators/comparators.ts",
    "content": "import * as comparators from './comparator';\nimport { Comparator } from './comparator.interface';\n\nclass Comparators {\n  constructor(\n    private availableComparators: Comparator[] = [comparators.DateComparator, comparators.NumberComparator]\n  ) {}\n\n  public compare(values: any[], order: string): Promise<string | void> {\n    const comparator = this.findComparator(values);\n\n    if (comparator === undefined) {\n      throw new Error(`Could not find comparator for ${values}.`);\n    }\n\n    return comparator.compare(values, order);\n  }\n\n  public findComparator(values: any[]): Comparator {\n    return this.availableComparators.find(comparator => comparator.isSatisfiedBy(values));\n  }\n\n  public addComparator(comparator: Comparator): void {\n    this.availableComparators.push(comparator);\n  }\n}\n\nexport const create = () => new Comparators();\n"
  },
  {
    "path": "src/comparators/index.ts",
    "content": "import { create } from './comparators';\n\nexport const comparators = create();\n"
  },
  {
    "path": "src/core/cli/cli.helper.spec.ts",
    "content": "import { isInitCommand, createTagsCLIArgument, getConfigPath, filterCLIArguments } from './cli.helper';\n\ndescribe('Cli helpers', () => {\n  it('returns false if missing parameters for init command', () => {\n    expect(isInitCommand()).toEqual(false);\n  });\n\n  it('returns false if args is not an array', () => {\n    expect(isInitCommand('some-args')).toEqual(false);\n  });\n\n  it('returns false when args length is lower than 2', () => {\n    expect(isInitCommand(['arg1'])).toEqual(false);\n  });\n\n  it('returns false when third argument is not init', () => {\n    expect(isInitCommand(['arg1', 'arg2', 'arg3'])).toEqual(false);\n  });\n\n  it('returns true when third argument is init', () => {\n    expect(isInitCommand(['arg1', 'arg2', 'init'])).toEqual(true);\n  });\n\n  it('returns default config path', () => {\n    expect(getConfigPath('some-file.config.js', undefined, '/my/path')).toEqual('/my/path/some-file.config.js');\n  });\n\n  it('returns config path by config file', () => {\n    expect(getConfigPath('some-file.config.js', 'other-config.ts', '/my/path')).toEqual('/my/path/other-config.ts');\n  });\n\n  it('creates empty tags cli argument if neither performance nor tags param is defined', () => {\n    expect(createTagsCLIArgument({})).toEqual([]);\n  });\n\n  it('creates cli argument without performance flag if only cucumber tags passed', () => {\n    expect(\n      createTagsCLIArgument({\n        tags: '@some-tag and @other-tag',\n      })\n    ).toEqual(['--cucumberOpts.tags', '@some-tag and @other-tag']);\n  });\n\n  it('creates cli argument with performance flag but without performance tag and without cucumber tags', () => {\n    expect(\n      createTagsCLIArgument({\n        performance: true,\n      })\n    ).toEqual(['--cucumberOpts.tags', '@performance']);\n  });\n\n  it('creates cli argument with performance flag but without performance tag and with cucumber tags', () => {\n    expect(\n      createTagsCLIArgument({\n        performance: true,\n        tags: '@some-tag and @other-tag',\n      })\n    ).toEqual(['--cucumberOpts.tags', '@some-tag and @other-tag and @performance']);\n  });\n\n  it('creates cli argument with performance flag but with performance tag and with cucumber tags', () => {\n    expect(\n      createTagsCLIArgument({\n        performance: true,\n        tags: '@some-tag and @other-tag and @performance',\n      })\n    ).toEqual(['--cucumberOpts.tags', '@some-tag and @other-tag and @performance']);\n  });\n\n  it('adds only not black listed arguments', () => {\n    expect(\n      filterCLIArguments(['myArg'])({\n        myArg: true,\n        otherArgument: false,\n      })\n    ).toEqual(['--otherArgument']);\n  });\n\n  it('adds bool not black listed arguments without parameters', () => {\n    expect(\n      filterCLIArguments(['myArg'])({\n        myArg: true,\n        otherArgument: false,\n      })\n    ).toEqual(['--otherArgument']);\n  });\n\n  it('adds string not black listed arguments with parameters', () => {\n    expect(\n      filterCLIArguments(['myArg'])({\n        myArg: 'some-value',\n        otherArgument: 'some-value',\n      })\n    ).toEqual(['--otherArgument=some-value']);\n  });\n});\n"
  },
  {
    "path": "src/core/cli/cli.helper.ts",
    "content": "import * as path from 'path';\n\nexport const isInitCommand = (args?: any[] | string) => {\n  if (Array.isArray(args)) {\n    return args.length > 2 && args[2] === 'init';\n  }\n\n  return false;\n};\n\nexport const getConfigPath = (configFile, argsConfig, basePath) => {\n  return argsConfig ? path.join(basePath, argsConfig) : path.join(basePath, configFile);\n};\n\nexport const createTagsCLIArgument = commandArgs => {\n  const tags = [];\n\n  if (commandArgs.performance) {\n    if (commandArgs.tags !== undefined && commandArgs.tags.indexOf('@performance') < 0) {\n      tags.push('--cucumberOpts.tags');\n      tags.push(`${commandArgs.tags} and @performance`);\n    } else if (commandArgs.tags === undefined) {\n      tags.push('--cucumberOpts.tags');\n      tags.push('@performance');\n    } else {\n      tags.push('--cucumberOpts.tags');\n      tags.push(commandArgs.tags);\n    }\n  } else if (commandArgs.tags !== undefined) {\n    tags.push('--cucumberOpts.tags');\n    tags.push(commandArgs.tags);\n  }\n\n  return tags;\n};\n\nexport const filterCLIArguments = blackList => commandArgs => {\n  const commandLineArgs = [];\n\n  for (const prop in commandArgs) {\n    if (prop !== '_' && !blackList.includes(prop)) {\n      if (commandArgs[prop] === true || commandArgs[prop] === false) {\n        commandLineArgs.push(`--${prop}`);\n      } else {\n        commandLineArgs.push(`--${prop}=${commandArgs[prop]}`);\n      }\n    }\n  }\n\n  return commandLineArgs;\n};\n"
  },
  {
    "path": "src/core/cli/initializer.ts",
    "content": "import * as fs from 'fs';\nimport * as inquirer from 'inquirer';\nimport * as mkdirp from 'mkdirp';\nimport * as path from 'path';\n\nclass Initializer {\n  public createProjectDirectory(dirPath) {\n    const projectPath = process.cwd() + dirPath;\n\n    mkdirp(projectPath, null);\n\n    console.log(`Created directory at path ${projectPath}`);\n  }\n\n  public createTemplateFile(templatePath, content) {\n    const filePath = process.cwd() + templatePath;\n\n    fs.writeFileSync(filePath, content);\n\n    console.log(`Created file at path ${filePath}`);\n  }\n\n  public createTemplateFileWithContentFrom(contentPath, file) {\n    const content = fs.readFileSync(path.join(__dirname, `../../../templates/${file}`));\n\n    this.createTemplateFile(contentPath, content);\n  }\n\n  public async promptFolders(message, defaultValue, type = 'input') {\n    let fullMessage = message;\n\n    if (defaultValue !== '') {\n      fullMessage += ` [${defaultValue}]`;\n    }\n\n    return inquirer\n      .prompt([\n        {\n          type,\n          name: 'input',\n          message: fullMessage,\n        },\n      ])\n      .then((answer: any): any => (answer.input === '' ? defaultValue : answer.input));\n  }\n\n  public async initConfig(commandArgs) {\n    const conf = {\n      baseUrl: '',\n      type: 'otherWeb',\n      browserWidth: 1600,\n      browserHeight: 900,\n      timeout: 60,\n      intervalEmail: 5,\n      maxEmailRepeats: 5,\n      elementsVisibilityTimeout: 5,\n      waitForPageTimeout: 5,\n      downloadTimeout: 30,\n      emails: ['/emails'],\n      reports: '/reports',\n      downloads: '/downloads',\n      data: '/data',\n      features: ['/features'],\n      pages: ['/pages'],\n      matchers: ['/matchers'],\n      generators: ['/generators'],\n      form_handlers: ['/form_handlers'],\n      step_definitions: ['/step_definitions'],\n      comparators: ['/comparators'],\n      dictionaries: ['/dictionaries'],\n      transformers: ['/transformers'],\n      regexes: ['/regexes'],\n      hooks: ['/hooks'],\n      clearEmailInboxBeforeTests: false,\n      clearCookiesAfterScenario: true,\n      clearLocalStorageAfterScenario: true,\n      email: null,\n      headless: false,\n      noGpu: false,\n      browserMob: null,\n      accounts: null,\n    };\n\n    if (typeof commandArgs.baseUrl === 'undefined') {\n      conf.baseUrl = await this.promptFolders('What is base url?', 'http://localhost:3000');\n    } else {\n      conf.baseUrl = commandArgs.baseUrl;\n    }\n\n    if (typeof commandArgs.emailType === 'undefined') {\n      await inquirer\n        .prompt([\n          {\n            type: 'rawlist',\n            name: 'type',\n            message: 'What kind of email service would you like to use?',\n            choices: [\n              { name: 'None', value: 'none' },\n              { name: 'Custom (you will have to fill configuration on your own)', value: 'custom' },\n              { name: 'MailTrap', value: 'mailtrap' },\n            ],\n          },\n        ])\n        .then((answer: any) => {\n          if (answer.type !== 'none') {\n            conf.email = {\n              type: answer.type,\n            };\n          }\n        });\n    } else {\n      conf.email = {\n        type: commandArgs.emailType,\n      };\n    }\n\n    if (conf.email && conf.email.type === 'mailtrap') {\n      conf.email = {\n        ...conf.email,\n        config: {\n          url: 'https://mailtrap.io',\n          apiKey: '',\n          inboxId: '',\n        },\n      };\n\n      if (typeof commandArgs.emailApiKey === 'undefined') {\n        conf.email.config.apiKey = await this.promptFolders('Type in your mailtrap apikey:', conf.email.config.apiKey);\n      } else {\n        conf.email.config.apiKey = commandArgs.emailApiKey;\n      }\n\n      if (typeof commandArgs.emailInboxId === 'undefined') {\n        conf.email.config.inboxId = await this.promptFolders(\n          'Type in your mailtrap inboxId:',\n          conf.email.config.inboxId\n        );\n      } else {\n        conf.email.config.inboxId = commandArgs.emailInboxId;\n      }\n    }\n\n    if (commandArgs.advanced) {\n      await this.initEnv();\n      conf.browserWidth = parseInt(await this.promptFolders('What is desired browser width?', conf.browserWidth));\n      conf.browserHeight = parseInt(await this.promptFolders('What is desired browser height?', conf.browserHeight));\n\n      conf.timeout = parseInt(await this.promptFolders('What is desired step timeout in seconds?', conf.timeout));\n      conf.intervalEmail = parseInt(\n        await this.promptFolders('What is desired step email interval in seconds?', conf.intervalEmail)\n      );\n      conf.maxEmailRepeats = parseInt(\n        await this.promptFolders('How many times emails should be checked - maximum repeats?', conf.maxEmailRepeats)\n      );\n      conf.elementsVisibilityTimeout = parseInt(\n        await this.promptFolders(\n          'What is desired elements visibility timeout in seconds?',\n          conf.elementsVisibilityTimeout\n        )\n      );\n      conf.waitForPageTimeout = parseInt(\n        await this.promptFolders('How long should I wait for page to load in seconds?', conf.waitForPageTimeout)\n      );\n      conf.downloadTimeout = parseInt(\n        await this.promptFolders('How long should I wait for files to download in seconds?', conf.downloadTimeout)\n      );\n\n      conf.reports = await this.promptFolders('Where are your reports stored?', conf.reports);\n      conf.downloads = await this.promptFolders('Where are your downloads stored?', conf.downloads);\n      conf.data = await this.promptFolders('Where is your data stored?', conf.data);\n\n      conf.features = [await this.promptFolders('Where are your features stored?', conf.features[0])];\n      conf.pages = [await this.promptFolders('Where are your pages stored?', conf.pages[0])];\n      conf.matchers = [await this.promptFolders('Where are your matchers stored?', conf.matchers[0])];\n      conf.generators = [await this.promptFolders('Where are your generators stored?', conf.generators[0])];\n      conf.form_handlers = [await this.promptFolders('Where are your form handlers stored?', conf.form_handlers[0])];\n      conf.step_definitions = [\n        await this.promptFolders('Where are your step definitions stored?', conf.step_definitions[0]),\n      ];\n      conf.comparators = [await this.promptFolders('Where are your comparators stored?', conf.comparators[0])];\n      conf.dictionaries = [await this.promptFolders('Where are your dictionaries stored?', conf.dictionaries[0])];\n      conf.regexes = [await this.promptFolders('Where are your regexes stored?', conf.regexes[0])];\n      conf.hooks = [await this.promptFolders('Where are your hooks stored?', conf.hooks[0])];\n      conf.transformers = [await this.promptFolders('Where are your transformers stored?', conf.transformers[0])];\n\n      conf.clearEmailInboxBeforeTests = await this.promptFolders(\n        'Should email inbox be cleared before tests?',\n        conf.clearEmailInboxBeforeTests,\n        'confirm'\n      );\n      conf.clearCookiesAfterScenario = await this.promptFolders(\n        'Should cookies be cleared after scenario?',\n        conf.clearCookiesAfterScenario,\n        'confirm'\n      );\n      conf.clearLocalStorageAfterScenario = await this.promptFolders(\n        'Should local storage be cleared after scenario?',\n        conf.clearLocalStorageAfterScenario,\n        'confirm'\n      );\n      conf.browserMob = {\n        serverPort: parseInt(await this.promptFolders('Define port where browsermob-proxy is running!', 8887)),\n        port: parseInt(await this.promptFolders('Define port where browsermob-proxy should be listening!', 8888)),\n        host: await this.promptFolders('Define host where browsermob-proxy is running!', 'localhost'),\n      };\n    }\n\n    conf.accounts = {\n      someAccount: {\n        accounts: [\n          {\n            email: '',\n            password: '',\n          },\n        ],\n      },\n    };\n\n    this.createTemplateFile('/kakunin.conf.js', 'module.exports = ' + JSON.stringify(conf, null, 4));\n  }\n\n  public async initEnv() {\n    const envs = [];\n\n    envs.push('FIXTURES_RELOAD_HOST=' + (await this.promptFolders('Define FIXTURES_RELOAD_HOST', '')));\n\n    this.createTemplateFile('/.env', envs.join('\\n'));\n  }\n\n  public async generateProjectStructure() {\n    const config = require(process.cwd() + '/kakunin.conf.js');\n\n    this.createProjectDirectory(config.reports);\n    this.createProjectDirectory(path.join(config.reports, 'report'));\n    this.createProjectDirectory(path.join(config.reports, 'json-output-folder'));\n    this.createProjectDirectory(path.join(config.reports, 'report', 'features'));\n    this.createProjectDirectory(path.join(config.reports, 'performance'));\n    this.createProjectDirectory(config.downloads);\n    this.createProjectDirectory(config.data);\n\n    this.createProjectDirectory(config.features[0]);\n    this.createProjectDirectory(config.pages[0]);\n    this.createProjectDirectory(config.matchers[0]);\n    this.createProjectDirectory(config.generators[0]);\n    this.createProjectDirectory(config.form_handlers[0]);\n    this.createProjectDirectory(config.step_definitions[0]);\n    this.createProjectDirectory(config.comparators[0]);\n    this.createProjectDirectory(config.dictionaries[0]);\n    this.createProjectDirectory(config.regexes[0]);\n    this.createProjectDirectory(config.hooks[0]);\n    this.createProjectDirectory(config.transformers[0]);\n    this.createProjectDirectory(config.emails[0]);\n\n    this.createTemplateFile(path.join(config.downloads, '.gitkeep'), '');\n    this.createTemplateFile(path.join(config.reports, 'json-output-folder', '.gitkeep'), '');\n    this.createTemplateFile(path.join(config.reports, 'report', '.gitkeep'), '');\n    this.createTemplateFile(path.join(config.reports, 'report', 'features', '.gitkeep'), '');\n    this.createTemplateFile(path.join(config.reports, 'performance', '.gitkeep'), '');\n    this.createTemplateFileWithContentFrom(config.features[0] + '/example.feature', 'example.feature');\n    this.createTemplateFileWithContentFrom(config.pages[0] + '/page.js', 'page.js');\n    this.createTemplateFileWithContentFrom(config.matchers[0] + '/matcher.js', 'matcher.js');\n    this.createTemplateFileWithContentFrom(config.generators[0] + '/generator.js', 'generator.js');\n    this.createTemplateFileWithContentFrom(config.step_definitions[0] + '/steps.js', 'steps.js');\n    this.createTemplateFileWithContentFrom(config.regexes[0] + '/regex.js', 'regex.js');\n    this.createTemplateFileWithContentFrom(config.hooks[0] + '/hook.js', 'hook.js');\n  }\n}\n\nexport default new Initializer();\n"
  },
  {
    "path": "src/core/config.helper.ts",
    "content": "const commandArgs = require('minimist')(process.argv.slice(2));\nlet config;\n\nif (process.env.NODE_ENV === 'test') {\n  config = {\n    projectPath: process.cwd(),\n    email: {\n      config: {},\n    },\n  };\n} else {\n  const configFile = process.argv.find(name => name.indexOf('--config') >= 0);\n  const configFilePath = configFile.substr(configFile.indexOf('=') + 1);\n\n  const project = process.argv.find(name => name.indexOf('--projectPath') >= 0);\n  const projectPath = project.substr(project.indexOf('=') + 1);\n\n  config = require(configFilePath);\n  config.projectPath = projectPath;\n  config.performance = commandArgs.performance || false;\n}\n\nexport default config;\n"
  },
  {
    "path": "src/core/fs/delete-files.helper.ts",
    "content": "import * as fs from 'fs';\nimport * as path from 'path';\n\nexport const deleteReports = directory => {\n  return fs\n    .readdirSync(directory)\n    .filter(file => fs.statSync(path.join(directory, file)).isFile() && file !== '.gitkeep')\n    .forEach(file => fs.unlinkSync(path.join(directory, file)));\n};\n"
  },
  {
    "path": "src/core/fs/prepare-catalogs.helper.ts",
    "content": "import * as fs from 'fs';\nimport * as mkdirp from 'mkdirp';\n\nexport const prepareCatalogs = directory => {\n  if (fs.existsSync(directory)) {\n    return Promise.resolve();\n  }\n\n  mkdirp(directory, null);\n  console.log(`${directory} has been added!`);\n  fs.writeFileSync(`${directory}/.gitkeep`, '');\n};\n"
  },
  {
    "path": "src/core/modules-loader.helper.ts",
    "content": "import * as fs from 'fs';\nimport * as path from 'path';\nimport config from './config.helper';\n\nclass ModulesLoader {\n  private paths: any;\n\n  constructor(configuration) {\n    this.paths = {\n      comparators: [],\n      dictionaries: [],\n      form_handlers: [],\n      generators: [],\n      matchers: [],\n      regexes: [],\n      transformers: [],\n      emails: [],\n      hooks: [],\n    };\n\n    Object.keys(this.paths).forEach(group => {\n      if (typeof config[group] !== 'undefined') {\n        configuration[group].forEach(groupPath => {\n          this.paths[group].push(path.join(configuration.projectPath + groupPath));\n        });\n      }\n    });\n  }\n\n  public getModules(group) {\n    return this.getFilePaths(this.paths[group]).map(file => require(file[1]));\n  }\n\n  public getModulesAsObject(projectFolders) {\n    const modules = {};\n    const filePaths = this.getFilePaths(projectFolders);\n\n    filePaths.forEach(file => {\n      modules[file[0]] = require(file[1]);\n    });\n\n    return modules;\n  }\n\n  public getFilePaths(folders) {\n    let files = [];\n\n    folders.forEach(folder => {\n      if (fs.existsSync(folder)) {\n        files = files.concat(\n          fs\n            .readdirSync(folder)\n            .filter(file => file !== '.gitkeep' && file.indexOf('.spec.js') < 0)\n            .map(file => [file.substr(0, file.indexOf('.')), `${folder}/${file}`])\n        );\n      } else {\n        console.log(`Directory ${folder} does not exist.`);\n      }\n    });\n\n    return files;\n  }\n}\n\nexport const create = (configuration = config) => new ModulesLoader(configuration);\n"
  },
  {
    "path": "src/core/prototypes.ts",
    "content": "RegExp.escape = (text): string => {\n  return text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\n};\n"
  },
  {
    "path": "src/dictionaries/base.ts",
    "content": "class BaseDictionary {\n  public readonly name: string;\n  public readonly values: object;\n\n  constructor(name, values) {\n    this.name = name;\n    this.values = values;\n  }\n\n  public isSatisfiedBy(name: string): boolean {\n    return this.name === name;\n  }\n\n  public getMappedValue(key: string): string {\n    return this.values[key];\n  }\n}\n\nexport default BaseDictionary;\n"
  },
  {
    "path": "src/dictionaries/dictionaries.spec.ts",
    "content": "import { createDictionary as create, Base as BaseDictionary } from './';\nimport fakeDictionary = require('../tests/dictionaries/fake-dictionary');\n\nconst dictionaries = create();\n\ndictionaries.addDictionary(fakeDictionary);\n\ndescribe('Dictionaries', () => {\n  it('throws an error when no dictionary was found', () => {\n    expect(() => dictionaries.getMappedValue('unknown-dictionary', 'unknown-key')).toThrow(\n      'Could not find dictionary for unknown-dictionary.'\n    );\n  });\n\n  it('returns mapped value for given key', () => {\n    expect(dictionaries.getMappedValue('fake-dictionary', 'some-key')).toEqual('some-value');\n  });\n\n  it('returns mapped value for given key - directly from dictionaries', () => {\n    expect(dictionaries.findMappedValueByPhrase('d:fake-dictionary:some-key')).toEqual('some-value');\n  });\n\n  it('adds a dictionary', () => {\n    const customDictionary = new BaseDictionary('my-dictionary', { 'some-key': 'mapped-some-key' });\n\n    dictionaries.addDictionary(customDictionary);\n\n    expect(dictionaries.getMappedValue('my-dictionary', 'some-key')).toEqual('mapped-some-key');\n  });\n});\n"
  },
  {
    "path": "src/dictionaries/dictionaries.ts",
    "content": "import Dictionary from './base';\n\nexport class Dictionaries {\n  constructor(private availableDictionaries: Dictionary[] = []) {}\n\n  public getMappedValue(dictionaryName: string, key: string): string {\n    const dic = this.findDictionary(dictionaryName);\n\n    if (dic === undefined) {\n      throw new Error(`Could not find dictionary for ${dictionaryName}.`);\n    }\n\n    return dic.getMappedValue(key);\n  }\n\n  public findDictionary(name: string): Dictionary {\n    return this.availableDictionaries.find(dic => dic.isSatisfiedBy(name));\n  }\n\n  public findMappedValueByPhrase(phrase: string): string {\n    const parameters = phrase.split(':');\n    if (parameters[0] === 'd') {\n      const dictionary = this.findDictionary(parameters[1]);\n\n      if (dictionary) {\n        return this.getMappedValue(parameters[1], parameters[2]);\n      }\n    }\n\n    return phrase;\n  }\n\n  public addDictionary(dictionary: Dictionary): void {\n    this.availableDictionaries.push(dictionary);\n  }\n}\n\nexport const create = () => new Dictionaries();\n"
  },
  {
    "path": "src/dictionaries/index.ts",
    "content": "import BaseDictionary from './base';\nimport { create } from './dictionaries';\n\nexport { Dictionaries } from './dictionaries';\nexport const createDictionary = create;\nexport const dictionaries = create();\nexport const Base = BaseDictionary;\n"
  },
  {
    "path": "src/emails/adapter/mailtrap.client.spec.ts",
    "content": "import { create } from './mailtrap.client';\nimport * as fetchMock from 'fetch-mock';\n\ndescribe('Mailtrap client', () => {\n  it('it returns mailtrap config', () => {\n    const mailtrapClient = create(undefined, {\n      config: {\n        apiKey: 'fake-api-key',\n        inboxId: 'fake-inbox-id',\n        url: 'http://fake-url.com',\n      },\n    });\n\n    expect(mailtrapClient.getMailtrapConfig()).toEqual({\n      apiKey: 'fake-api-key',\n      inboxId: 'fake-inbox-id',\n      endpoint: 'http://fake-url.com',\n    });\n  });\n\n  it('clears inbox', done => {\n    const apiKey = 'fake-api-key';\n    const inbox = 'fake-inbox-id';\n    const url = 'http://fake-url.com';\n\n    const requestMock: any = fetchMock\n      .sandbox()\n      .mock(`${url}/api/v1/inboxes/${inbox}/clean?api_token=${apiKey}`, { data: 'cleared' }, { method: 'PATCH' });\n\n    const mailtrapClient = create(requestMock, {\n      config: {\n        apiKey: apiKey,\n        inboxId: inbox,\n        url: url,\n      },\n    });\n\n    mailtrapClient.clearInbox().then(res => {\n      expect(res).toEqual({ data: 'cleared' });\n      done();\n    });\n  });\n\n  it('returns not read emails', done => {\n    const apiKey = 'fake-api-key';\n    const inbox = 'fake-inbox-id';\n    const url = 'http://fake-url.com';\n\n    const emails = [\n      { subject: 's2', is_read: false, raw_path: `/api/v1/inboxes/${inbox}/messages/000000001/body.raw` },\n      { subject: 's3', is_read: true, raw_path: `/api/v1/inboxes/${inbox}/messages/000000002/body.raw` },\n      { subject: 's1', is_read: false, raw_path: `/api/v1/inboxes/${inbox}/messages/000000003/body.raw` },\n    ];\n\n    const requestMock: any = fetchMock\n      .sandbox()\n      .mock(`${url}/api/v1/inboxes/${inbox}/messages?api_token=${apiKey}`, emails, { method: 'GET' })\n      .mock(`${url}${emails[0].raw_path}?api_token=${apiKey}`, { method: 'GET' })\n      .mock(`${url}${emails[1].raw_path}?api_token=${apiKey}`, { method: 'GET' })\n      .mock(`${url}${emails[2].raw_path}?api_token=${apiKey}`, { method: 'GET' });\n\n    const mailtrapClient = create(requestMock, {\n      config: {\n        apiKey: apiKey,\n        inboxId: inbox,\n        url: url,\n      },\n    });\n\n    mailtrapClient.getEmails().then(res => {\n      expect(res.length).toEqual(2);\n      res.forEach(email => expect(email.is_read).toEqual(false));\n      done();\n    });\n  });\n\n  it('returns email attachments', done => {\n    const apiKey = 'fake-api-key';\n    const inbox = 'fake-inbox-id';\n    const url = 'http://fake-url.com';\n    const emailId = 'some-id';\n\n    const requestMock: any = fetchMock\n      .sandbox()\n      .mock(\n        `${url}/api/v1/inboxes/${inbox}/messages/${emailId}/attachments?api_token=${apiKey}`,\n        [{ id: 1, name: 'some-file', content: 'some-content' }],\n        {\n          method: 'GET',\n        }\n      );\n\n    const mailtrapClient = create(requestMock, {\n      config: {\n        apiKey: apiKey,\n        inboxId: inbox,\n        url: url,\n      },\n    });\n\n    mailtrapClient.getAttachments({ id: emailId }).then(res => {\n      expect(res).toEqual([{ id: 1, name: 'some-file', content: 'some-content' }]);\n      done();\n    });\n  });\n\n  it('marks email as read', done => {\n    const apiKey = 'fake-api-key';\n    const inbox = 'fake-inbox-id';\n    const url = 'http://fake-url.com';\n    const emailId = 'some-id';\n\n    const requestMock: any = fetchMock.sandbox().mock(\n      (reqUrl, opts) => {\n        return (\n          reqUrl === `${url}/api/v1/inboxes/${inbox}/messages/${emailId}?api_token=${apiKey}` &&\n          opts.body === JSON.stringify({ message: { is_read: true } })\n        );\n      },\n      { data: 'marked-as-read' },\n      {\n        method: 'PATCH',\n        headers: { 'Content-Type': 'application/json' },\n      }\n    );\n\n    const mailtrapClient = create(requestMock, {\n      config: {\n        apiKey: apiKey,\n        inboxId: inbox,\n        url: url,\n      },\n    });\n\n    mailtrapClient.markAsRead({ id: emailId }).then(res => {\n      expect(res).toEqual({ data: 'marked-as-read' });\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/emails/adapter/mailtrap.client.ts",
    "content": "import * as fetch from 'node-fetch';\nimport configuration from '../../core/config.helper';\n\nclass MailTrapClient {\n  private requestClient: any;\n  private config: any;\n\n  constructor(requestClient, config) {\n    this.requestClient = requestClient;\n    this.config = config;\n  }\n\n  public isSatisfiedBy(emailConfiguration) {\n    return (\n      emailConfiguration.type === 'mailtrap' &&\n      emailConfiguration.config.hasOwnProperty('apiKey') &&\n      emailConfiguration.config.hasOwnProperty('inboxId') &&\n      emailConfiguration.config.hasOwnProperty('url')\n    );\n  }\n\n  public getMailtrapConfig() {\n    return {\n      apiKey: this.config.config.apiKey,\n      inboxId: this.config.config.inboxId,\n      endpoint: this.config.config.url,\n    };\n  }\n\n  public clearInbox() {\n    const config = this.getMailtrapConfig();\n    const url = `${config.endpoint}/api/v1/inboxes/${config.inboxId}/clean?api_token=${config.apiKey}`;\n\n    return this.requestClient(url, {\n      method: 'PATCH',\n    }).then(res => {\n      if (res.status !== 200) {\n        throw new Error(res);\n      }\n\n      return res.json();\n    });\n  }\n\n  public async getEmails() {\n    const config = this.getMailtrapConfig();\n    const url = `${config.endpoint}/api/v1/inboxes/${config.inboxId}/messages?api_token=${config.apiKey}`;\n\n    const messages = await this.requestClient(url).then(res => {\n      if (res.status !== 200) {\n        throw new Error(res);\n      }\n\n      return res.json();\n    });\n\n    const messagesWithBody = [];\n\n    for (const message of messages) {\n      const rawBody = await this.requestClient(`${config.endpoint}${message.raw_path}?api_token=${config.apiKey}`).then(\n        res => res.text()\n      );\n\n      messagesWithBody.push({\n        ...message,\n        html_body: rawBody,\n      });\n    }\n\n    return messagesWithBody.filter(message => !message.is_read);\n  }\n\n  public getAttachments(email) {\n    const config = this.getMailtrapConfig();\n    const url = `${config.endpoint}/api/v1/inboxes/${config.inboxId}/messages/${email.id}/attachments?api_token=${\n      config.apiKey\n    }`;\n\n    return this.requestClient(url).then(res => {\n      if (res.status !== 200) {\n        throw new Error(res);\n      }\n\n      return res.json();\n    });\n  }\n\n  public markAsRead(email) {\n    const config = this.getMailtrapConfig();\n    const url = `${config.endpoint}/api/v1/inboxes/${config.inboxId}/messages/${email.id}?api_token=${config.apiKey}`;\n\n    return this.requestClient(url, {\n      method: 'PATCH',\n      headers: {\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify({\n        message: {\n          is_read: true,\n        },\n      }),\n    }).then(res => {\n      if (res.status !== 200) {\n        throw new Error(res);\n      }\n\n      return res.json();\n    });\n  }\n}\n\nexport const create = (requestClient = fetch, config = configuration.email) => {\n  return new MailTrapClient(requestClient, config);\n};\n"
  },
  {
    "path": "src/emails/email.service.spec.ts",
    "content": "import { create } from './email.service';\n\ndescribe('Email service', () => {\n  it('it returns adapter if found', () => {\n    const fakeAdapter = {\n      isSatisfiedBy: (config: any) => true,\n    };\n\n    const fakeConfig = {\n      email: {\n        type: 'some-service-type',\n      },\n    };\n\n    const emailService = create([fakeAdapter], fakeConfig);\n\n    expect(emailService.getAdapter()).toBe(fakeAdapter);\n  });\n\n  it('it throws error if adapter not found', () => {\n    const fakeConfig = {\n      email: {\n        type: 'some-service-type',\n      },\n    };\n\n    const emailService = create([], fakeConfig);\n\n    expect(() => emailService.getAdapter()).toThrow('Could not find email adapter for given configuration.');\n  });\n\n  it('it adds adapter', () => {\n    const fakeAdapter = {\n      isSatisfiedBy: config => true,\n    };\n\n    const fakeConfig = {\n      email: {\n        type: 'some-service-type',\n      },\n    };\n\n    const emailService = create([], fakeConfig);\n\n    expect(() => emailService.getAdapter()).toThrow('Could not find email adapter for given configuration.');\n\n    emailService.addAdapter(fakeAdapter);\n\n    expect(emailService.getAdapter()).toEqual(fakeAdapter);\n  });\n\n  it('it calls adapter clearInbox method', done => {\n    const fakeAdapter = {\n      isSatisfiedBy: config => true,\n      clearInbox: () => Promise.resolve(),\n    };\n\n    const fakeConfig = {\n      email: {\n        type: 'some-service-type',\n      },\n    };\n\n    const emailService = create([fakeAdapter], fakeConfig);\n\n    emailService.clearInbox().then(() => done());\n  });\n\n  it('it calls adapter getEmails method', done => {\n    const fakeAdapter = {\n      isSatisfiedBy: config => true,\n      getEmails: () => Promise.resolve(),\n    };\n\n    const fakeConfig = {\n      email: {\n        type: 'some-service-type',\n      },\n    };\n\n    const emailService = create([fakeAdapter], fakeConfig);\n\n    emailService.getEmails().then(() => done());\n  });\n\n  it('it calls adapter markAsRead method', done => {\n    const fakeAdapter = {\n      isSatisfiedBy: config => true,\n      markAsRead: email => Promise.resolve(email),\n    };\n\n    const fakeConfig = {\n      email: {\n        type: 'some-service-type',\n      },\n    };\n\n    const emailService = create([fakeAdapter], fakeConfig);\n\n    emailService.markAsRead('some@email.com').then(email => {\n      expect(email).toEqual('some@email.com');\n      done();\n    });\n  });\n\n  it('it calls adapter getAttachments method', done => {\n    const fakeAdapter = {\n      isSatisfiedBy: config => true,\n      getAttachments: email => Promise.resolve('some-attachment'),\n    };\n\n    const fakeConfig = {\n      email: {\n        type: 'some-service-type',\n      },\n    };\n\n    const emailService = create([fakeAdapter], fakeConfig);\n\n    emailService.getAttachments('some@email.com').then(attachment => {\n      expect(attachment).toEqual('some-attachment');\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/emails/email.service.ts",
    "content": "import configuration from '../core/config.helper';\nimport { create as createMailtrapAdapter } from './adapter/mailtrap.client';\n\nclass EmailService {\n  private config: any;\n  private availableAdapters: any;\n\n  constructor(config, defaultAdapters) {\n    this.config = config;\n\n    this.availableAdapters = defaultAdapters;\n  }\n\n  public clearInbox() {\n    const adapter = this.getAdapter();\n\n    return adapter.clearInbox();\n  }\n\n  public getEmails() {\n    const adapter = this.getAdapter();\n\n    return adapter.getEmails();\n  }\n\n  public getAttachments(email) {\n    const adapter = this.getAdapter();\n\n    return adapter.getAttachments(email);\n  }\n\n  public markAsRead(email) {\n    const adapter = this.getAdapter();\n\n    return adapter.markAsRead(email);\n  }\n\n  public addAdapter(adapter) {\n    this.availableAdapters.push(adapter);\n  }\n\n  public getAdapter() {\n    const emailAdapter = this.availableAdapters.find(adapter => adapter.isSatisfiedBy(this.config.email));\n\n    if (emailAdapter === undefined) {\n      throw new Error('Could not find email adapter for given configuration.');\n    }\n\n    return emailAdapter;\n  }\n}\n\nconst mailtrapAdapter = createMailtrapAdapter();\n\nexport const create = (defaultAdapters: any = [mailtrapAdapter], config = configuration) => {\n  return new EmailService(config, defaultAdapters);\n};\n"
  },
  {
    "path": "src/emails/filter/current-user.filter.ts",
    "content": "// TODO: stop injecting world here and use some kind of a user provider\n\nclass CurrentUserFilter {\n  public isSatisfiedBy(type) {\n    return type === 'currentUser';\n  }\n\n  public filter(emails, type, value, world) {\n    return emails.filter(email => email.to_email === world.currentUser.account.email);\n  }\n}\n\nexport const currentUserFilter = new CurrentUserFilter();\n"
  },
  {
    "path": "src/emails/filter/current-user.spec.ts",
    "content": "const { currentUserFilter } = require('./current-user.filter');\n\nconst fakeWorld = {\n  currentUser: {\n    account: {\n      email: 'some@email.com',\n    },\n  },\n};\n\ndescribe('Current user filter', () => {\n  it('returns true when can be use', () => {\n    expect(currentUserFilter.isSatisfiedBy('currentUser')).toEqual(true);\n  });\n\n  it('returns false when cannot be use', () => {\n    expect(currentUserFilter.isSatisfiedBy('unsupportedName')).toEqual(false);\n  });\n\n  it('returns only emails for current logged user', () => {\n    const fakeEmails = [\n      { to_email: 'unknown@user.com' },\n      { to_email: 'some@email.com' },\n      { to_email: 'unknown@user.com' },\n      { to_email: 'some@email.com' },\n    ];\n\n    const filteredEmails = currentUserFilter.filter(fakeEmails, 'currentUser', undefined, fakeWorld);\n\n    expect(filteredEmails.length).toEqual(2);\n\n    filteredEmails.forEach(email => expect(email.to_email).toEqual(fakeWorld.currentUser.account.email));\n  });\n});\n"
  },
  {
    "path": "src/emails/filter/index.ts",
    "content": "export * from './current-user.filter';\nexport * from './minimal-email-size.filter';\nexport * from './text-fields.filter';\n"
  },
  {
    "path": "src/emails/filter/minimal-email-size.filter.spec.ts",
    "content": "const { minimalEmailSizeFilter } = require('./minimal-email-size.filter.ts');\n\ndescribe('Minimal email size filter', () => {\n  it('returns true when can be use', () => {\n    expect(minimalEmailSizeFilter.isSatisfiedBy('minimalEmailSize')).toEqual(true);\n  });\n\n  it('returns false when cannot be use', () => {\n    expect(minimalEmailSizeFilter.isSatisfiedBy('unsupportedName')).toEqual(false);\n  });\n\n  it('returns only emails with a minimum size', () => {\n    const fakeEmails = [{ email_size: 400 }, { email_size: 500 }, { email_size: 666 }, { email_size: 30 }];\n\n    const filteredEmails = minimalEmailSizeFilter.filter(fakeEmails, 'minimalEmailSize', 500);\n\n    expect(filteredEmails.length).toEqual(2);\n\n    filteredEmails.forEach(email => expect(email.email_size).toBeGreaterThanOrEqual(500));\n  });\n});\n"
  },
  {
    "path": "src/emails/filter/minimal-email-size.filter.ts",
    "content": "class MinimalEmailSizeFilter {\n  public isSatisfiedBy(type) {\n    return type === 'minimalEmailSize';\n  }\n\n  public filter(emails, type, value) {\n    return emails.filter(email => email.email_size >= parseInt(value));\n  }\n}\n\nexport const minimalEmailSizeFilter = new MinimalEmailSizeFilter();\n"
  },
  {
    "path": "src/emails/filter/text-fields.filter.spec.ts",
    "content": "import { textFieldFilter } from './text-fields.filter';\nimport variableStore from '../../web/variable-store.helper';\n\ndescribe('Text fields filter', () => {\n  it('returns true when supported typ passed', () => {\n    const supportedTypes = ['subject', 'from_email', 'from_name', 'to_email', 'to_name', 'html_body', 'text_body'];\n\n    supportedTypes.forEach(type => expect(textFieldFilter.isSatisfiedBy(type)).toEqual(true));\n  });\n\n  it('returns false when not supported type passed', () => {\n    expect(textFieldFilter.isSatisfiedBy('unsupportedName')).toEqual(false);\n  });\n\n  it('throws an error when value is not a regex or text matcher', () => {\n    expect(() => textFieldFilter.filter(['some email content'], 'subject', 'some-value')).toThrow(\n      'Comparison type not specified. Please use r: for regex and t: for text'\n    );\n  });\n\n  it('returns only emails matching given value using t:v:variableName', () => {\n    const fakeEmails = [\n      {\n        subject: 'some-subject',\n        from_email: 'some@user.com',\n        from_name: 'Username',\n        to_email: 'other@user.com',\n        to_name: 'ToUsername',\n        html_body: 'Body 123',\n        text_body: 'Body 123',\n      },\n      {\n        subject: 'other-subject',\n        from_email: 'my@user.com',\n        from_name: 'My Username',\n        to_email: 'to@user.com',\n        to_name: 'Username123',\n        html_body: 'Complicated body 12.12.2016',\n        text_body: 'Complicated body 12.12.2016',\n      },\n    ];\n\n    variableStore.storeVariable('someVariable', 'some-subject');\n\n    const filteredEmails = textFieldFilter.filter(fakeEmails, 'subject', 't:v:someVariable');\n\n    expect(filteredEmails.length).toEqual(1);\n\n    filteredEmails.forEach(email => expect(email.subject === 'some-subject').toEqual(true));\n  });\n\n  it('returns only emails matching given value using r:regexpName', () => {\n    const fakeEmails = [\n      {\n        subject: 'some-subject',\n        from_email: 'some@user.com',\n        from_name: 'Username',\n        to_email: 'other@user.com',\n        to_name: 'ToUsername',\n        html_body: 'Body 123',\n        text_body: 'Body 123',\n      },\n      {\n        subject: 'other-subject',\n        from_email: 'my@user.com',\n        from_name: 'My Username',\n        to_email: 'to@user.com',\n        to_name: 'Username123',\n        html_body: 'Complicated body',\n        text_body: 'Complicated body',\n      },\n    ];\n\n    const filteredEmails = textFieldFilter.filter(fakeEmails, 'text_body', 'r:number');\n\n    expect(filteredEmails.length).toEqual(1);\n\n    filteredEmails.forEach(email => expect(email.text_body === 'Body 123').toEqual(true));\n  });\n});\n"
  },
  {
    "path": "src/emails/filter/text-fields.filter.ts",
    "content": "import { regexBuilder } from '../../matchers';\nimport variableStore from '../../web/variable-store.helper';\n\nclass TextFieldFilter {\n  public isSatisfiedBy(type) {\n    return ['subject', 'from_email', 'from_name', 'to_email', 'to_name', 'html_body', 'text_body'].indexOf(type) !== -1;\n  }\n\n  public filter(emails, type, value) {\n    return emails.filter(email => {\n      if (value.startsWith('r:')) {\n        return regexBuilder.buildRegex(value).test(email[type]);\n      }\n\n      if (value.startsWith('t:')) {\n        return new RegExp(RegExp.escape(variableStore.replaceTextVariables(value.substr(2)))).test(email[type]);\n      }\n\n      throw new Error('Comparison type not specified. Please use r: for regex and t: for text');\n    });\n  }\n}\n\nexport const textFieldFilter = new TextFieldFilter();\n"
  },
  {
    "path": "src/emails/filters.spec.ts",
    "content": "import { filters } from './filters';\n\nconst world = {\n  currentUser: {\n    account: {\n      email: 'some@email.com',\n    },\n  },\n};\n\ndescribe('Email filters', () => {\n  it('throws an error when no filter was found', () => {\n    expect(() => filters.filter(['some email content'], 'unknown-filter-type', 'some-value', world)).toThrow(\n      'Could not find filter for unknown-filter-type.'\n    );\n  });\n\n  it('return emails matching given filter', () => {\n    const emails = [\n      { to_email: 'other@email.com' },\n      { to_email: 'some@email.com' },\n      { to_email: 'other@email.com' },\n      { to_email: 'some@email.com' },\n      { to_email: 'other@email.com' },\n      { to_email: 'some@email.com' },\n    ];\n\n    const filteredEmails = filters.filter(emails, 'currentUser', undefined, world);\n\n    expect(filteredEmails.length).toEqual(3);\n\n    filteredEmails.forEach(email => expect(email.to_email).toEqual('some@email.com'));\n  });\n});\n"
  },
  {
    "path": "src/emails/filters.ts",
    "content": "import * as defaultFilters from './filter';\n\nclass Filters {\n  private availableFilters: any;\n\n  constructor() {\n    this.availableFilters = [\n      defaultFilters.currentUserFilter,\n      defaultFilters.minimalEmailSizeFilter,\n      defaultFilters.textFieldFilter,\n    ];\n  }\n\n  public filter(emails, type, value, world) {\n    const filter = this.findFilter(type);\n\n    if (typeof filter === 'undefined') {\n      throw new Error(`Could not find filter for ${type}.`);\n    }\n\n    return filter.filter(emails, type, value, world);\n  }\n\n  public findFilter(type) {\n    return this.availableFilters.find(filter => filter.isSatisfiedBy(type));\n  }\n}\n\nexport const filters = new Filters();\n"
  },
  {
    "path": "src/emails/index.ts",
    "content": "import { create } from './email.service';\n\nexport const emailService = create();\n"
  },
  {
    "path": "src/form-handlers/form-handler.interface.ts",
    "content": "export interface FormHandler {\n  isSatisfiedBy(element?: object, elementName?: string): Promise<boolean>;\n  handleFill(page: object, elementName: string, desiredValue: string): Promise<string | void>;\n  handleCheck(page: object, elementName: string, desiredValue: string): Promise<string | void>;\n  getPriority(): number;\n}\n"
  },
  {
    "path": "src/form-handlers/handler/checkbox.handler.ts",
    "content": "import { FormHandler } from '../form-handler.interface';\n\nclass CheckboxHandler implements FormHandler {\n  public isSatisfiedBy(element) {\n    return element.getTagName().then(tagName => {\n      if (tagName === 'input') {\n        return element.getAttribute('type').then(inputType => inputType === 'checkbox');\n      }\n\n      if (tagName instanceof Array) {\n        return element\n          .first()\n          .getAttribute('type')\n          .then(inputType => inputType === 'checkbox');\n      }\n\n      return false;\n    });\n  }\n\n  public handleFill(page, elementName, desiredValue) {\n    return page\n      .getElements(elementName)\n      .filter(elem => {\n        return elem\n          .element(by.xpath('..'))\n          .getText()\n          .then(text => {\n            return text.trim() === desiredValue;\n          });\n      })\n      .first()\n      .click();\n  }\n\n  public handleCheck(page, elementName, desiredValue) {\n    const filteredElements = page.getElements(elementName).filter(element => element.isSelected());\n\n    return filteredElements.count().then(count => {\n      if (desiredValue === '') {\n        if (count === 0) {\n          return Promise.resolve();\n        }\n\n        return Promise.reject(`Expected count to be 0 got ${count}`);\n      }\n\n      return page\n        .getElements(elementName)\n        .filter(element => {\n          return element\n            .element(by.xpath('..'))\n            .getText()\n            .then(text => {\n              return text.trim() === desiredValue;\n            });\n        })\n        .first()\n        .isSelected()\n        .then(selected => {\n          if (selected) {\n            return Promise.resolve();\n          }\n\n          return Promise.reject(`Expected element ${elementName} to be selected`);\n        });\n    });\n  }\n\n  public getPriority() {\n    return 998;\n  }\n}\n\nexport const checkboxHandler = new CheckboxHandler();\n"
  },
  {
    "path": "src/form-handlers/handler/ckeditor.handler.ts",
    "content": "import { FormHandler } from '../form-handler.interface';\n\nclass CKEditorHandler implements FormHandler {\n  public isSatisfiedBy(element, elementName) {\n    return Promise.resolve(elementName.endsWith('CKEditor'));\n  }\n\n  public handleFill(page, elementName, desiredValue) {\n    browser.switchTo().frame(page[elementName].getWebElement());\n\n    browser.driver.findElement(by.tagName('body')).sendKeys(desiredValue);\n\n    browser.switchTo().defaultContent();\n\n    return browser.waitForAngular();\n  }\n\n  public handleCheck(page, elementName, desiredValue) {\n    return Promise.reject('Checking CKEditor is not supported');\n  }\n\n  public getPriority() {\n    return 998;\n  }\n}\n\nexport const ckEditorHandler = new CKEditorHandler();\n"
  },
  {
    "path": "src/form-handlers/handler/custom-angular-select.handler.ts",
    "content": "import { FormHandler } from '../form-handler.interface';\n\nclass CustomAngularSelectHandler implements FormHandler {\n  private selectedOptionSelector: object;\n  private optionsSelector: object;\n\n  constructor() {\n    this.optionsSelector = by.css('ul.ui-select-choices li a.ui-select-choices-row-inner');\n    this.selectedOptionSelector = by.css('div.ui-select-match .ui-select-match-text');\n  }\n\n  public isSatisfiedBy(element, elementName) {\n    return Promise.resolve(elementName.endsWith('CustomAngularSelect'));\n  }\n\n  public handleFill(page, elementName, desiredValue) {\n    return browser\n      .executeScript('arguments[0].scrollIntoView(false);', page[elementName].getWebElement())\n      .then(() => page[elementName].click())\n      .then(() => {\n        const filtered = page[elementName]\n          .all(this.optionsSelector)\n          .filter(elem => elem.getText().then(text => text === desiredValue));\n\n        return filtered.count().then(count => {\n          if (count === 0) {\n            return page[elementName]\n              .all(this.optionsSelector)\n              .first()\n              .click();\n          }\n\n          return filtered.first().click();\n        });\n      });\n  }\n\n  public handleCheck(page, elementName, desiredValue) {\n    return page[elementName]\n      .element(this.selectedOptionSelector)\n      .getText()\n      .then(text => {\n        if (text === desiredValue) {\n          return Promise.resolve();\n        }\n\n        return Promise.reject(`Expected ${desiredValue} got ${text} for select element ${elementName}`);\n      });\n  }\n\n  public getPriority() {\n    return 998;\n  }\n}\n\nexport const customAngularSelectHandler = new CustomAngularSelectHandler();\n"
  },
  {
    "path": "src/form-handlers/handler/default.handler.ts",
    "content": "import { FormHandler } from '../form-handler.interface';\n\nclass DefaultHandler implements FormHandler {\n  public isSatisfiedBy() {\n    return Promise.resolve(true);\n  }\n\n  public handleFill(page, elementName, desiredValue) {\n    return page\n      .getElement(elementName)\n      .isDisplayed()\n      .then(() => page.getElement(elementName).clear())\n      .then(() => page.getElement(elementName).sendKeys(desiredValue));\n  }\n\n  public handleCheck(page, elementName, desiredValue) {\n    return page\n      .getElement(elementName)\n      .isDisplayed()\n      .then(() => {\n        return page\n          .getElement(elementName)\n          .getAttribute('value')\n          .then(value => {\n            if (value === desiredValue) {\n              return Promise.resolve();\n            }\n\n            return Promise.reject(`Expected ${desiredValue} got ${value} for text input element ${elementName}`);\n          });\n      });\n  }\n\n  public getPriority() {\n    return 999;\n  }\n}\n\nexport const defaultHandler = new DefaultHandler();\n"
  },
  {
    "path": "src/form-handlers/handler/file.handler.ts",
    "content": "import * as path from 'path';\nimport config from '../../core/config.helper';\nimport { FormHandler } from '../form-handler.interface';\n\nclass FileHandler implements FormHandler {\n  public isSatisfiedBy(element) {\n    return element.getTagName().then(tagName => {\n      if (tagName === 'input') {\n        return element.getAttribute('type').then(inputType => inputType === 'file');\n      }\n\n      if (tagName instanceof Array) {\n        return element\n          .first()\n          .getAttribute('type')\n          .then(inputType => inputType === 'file');\n      }\n\n      return false;\n    });\n  }\n\n  public handleFill(page, elementName, desiredValue) {\n    const fileToUpload = path.resolve(path.join(config.projectPath, config.data, desiredValue));\n\n    return page.getElements(elementName).sendKeys(fileToUpload);\n  }\n\n  public handleCheck(page, elementName, desiredValue) {\n    return page\n      .getElements(elementName)\n      .getText()\n      .then(text => {\n        if (text === desiredValue) {\n          return Promise.resolve();\n        }\n\n        return Promise.reject(`Expected ${desiredValue} got ${text} for file element ${elementName}`);\n      });\n  }\n\n  public getPriority() {\n    return 998;\n  }\n}\n\nexport const fileHandler = new FileHandler();\n"
  },
  {
    "path": "src/form-handlers/handler/index.ts",
    "content": "export * from './checkbox.handler';\nexport * from './ckeditor.handler';\nexport * from './custom-angular-select.handler';\nexport * from './default.handler';\nexport * from './file.handler';\nexport * from './uploaded-file.handler';\nexport * from './radio.handler';\nexport * from './select.handler';\n"
  },
  {
    "path": "src/form-handlers/handler/radio.handler.ts",
    "content": "import { FormHandler } from '../form-handler.interface';\n\nclass RadioHandler implements FormHandler {\n  public isSatisfiedBy(element) {\n    return element.getTagName().then(tagName => {\n      if (tagName === 'input') {\n        return element.getAttribute('type').then(inputType => inputType === 'radio');\n      }\n\n      if (tagName instanceof Array) {\n        return element\n          .first()\n          .getAttribute('type')\n          .then(inputType => inputType === 'radio');\n      }\n\n      return false;\n    });\n  }\n\n  public handleFill(page, elementName, desiredValue) {\n    const firstRadio = page\n      .getElements(elementName)\n      .filter(elem => elem.getAttribute('value').then(elemValue => elemValue === desiredValue))\n      .first();\n\n    return firstRadio.isDisplayed().then(isDisplayed => {\n      if (isDisplayed) {\n        return firstRadio.click();\n      }\n\n      return firstRadio.element(by.xpath('..')).click();\n    });\n  }\n\n  public handleCheck(page, elementName, desiredValue) {\n    const filteredElements = page.getElements(elementName).filter(element => element.isSelected());\n\n    return filteredElements.count().then(count => {\n      if (desiredValue === '') {\n        if (count === 0) {\n          return Promise.resolve();\n        }\n\n        return Promise.reject(`Expected count to be 0 got ${count}`);\n      }\n\n      return filteredElements\n        .first()\n        .getAttribute('value')\n        .then(value => {\n          if (value === desiredValue) {\n            return Promise.resolve();\n          }\n\n          return Promise.reject(`Expected ${desiredValue} got ${value} for radio element ${elementName}`);\n        });\n    });\n  }\n\n  public getPriority() {\n    return 998;\n  }\n}\n\nexport const radioHandler = new RadioHandler();\n"
  },
  {
    "path": "src/form-handlers/handler/select.handler.ts",
    "content": "import { FormHandler } from '../form-handler.interface';\n\nclass SelectHandler implements FormHandler {\n  private optionsSelector: object;\n\n  constructor() {\n    this.optionsSelector = by.css('option');\n  }\n\n  public isSatisfiedBy(element) {\n    return element.getTagName().then(tagName => tagName === 'select');\n  }\n\n  public handleFill(page, elementName, desiredValue) {\n    const self = this;\n\n    const filteredByText = page\n      .getElements(elementName)\n      .all(this.optionsSelector)\n      .filter(elem => elem.getText().then(text => text.trim() === desiredValue));\n\n    return filteredByText.count().then(filteredByTextCount => {\n      if (filteredByTextCount === 0) {\n        const filteredByValue = page\n          .getElements(elementName)\n          .all(by.css('option'))\n          .filter(elem => elem.getAttribute('value').then(elemValue => elemValue === desiredValue));\n\n        return filteredByValue.count().then(filteredByValueCount => {\n          if (filteredByValueCount === 0) {\n            return page[elementName]\n              .all(self.optionsSelector)\n              .first()\n              .click();\n          }\n\n          return filteredByValue.first().click();\n        });\n      }\n\n      return filteredByText.first().click();\n    });\n  }\n\n  public handleCheck(page, elementName, desiredValue) {\n    return page\n      .getElement(elementName)\n      .all(this.optionsSelector)\n      .filter(element => element.getAttribute('value').then(elemValue => elemValue === desiredValue))\n      .count()\n      .then(count => {\n        if (count === 1) {\n          return Promise.resolve();\n        }\n\n        return Promise.reject('Option not found for select element.');\n      });\n  }\n\n  public getPriority() {\n    return 998;\n  }\n}\n\nexport const selectHandler = new SelectHandler();\n"
  },
  {
    "path": "src/form-handlers/handler/uploaded-file.handler.ts",
    "content": "import { FormHandler } from '../form-handler.interface';\n\nclass UploadedFileHandler implements FormHandler {\n  public isSatisfiedBy(element, elementName) {\n    return Promise.resolve(elementName.endsWith('Uploaded'));\n  }\n\n  public handleFill(page, elementName, desiredValue) {\n    return Promise.reject('Not supported for this field type');\n  }\n\n  public handleCheck(page, elementName, desiredValue) {\n    return page[elementName].getText().then(text => {\n      if (text.indexOf(desiredValue) >= 0) {\n        return Promise.resolve();\n      }\n\n      return Promise.reject(`Expected ${desiredValue} got ${text} for file element ${elementName}`);\n    });\n  }\n\n  public getPriority() {\n    return 998;\n  }\n}\n\nexport const uploadedFileHandler = new UploadedFileHandler();\n"
  },
  {
    "path": "src/form-handlers/handlers.ts",
    "content": "import * as formHandler from './handler';\nimport { FormHandler } from './form-handler.interface';\nimport Base from '../pages/base';\n\nclass FormHandlers {\n  constructor(\n    private availableHandlers: FormHandler[] = [\n      formHandler.checkboxHandler,\n      formHandler.ckEditorHandler,\n      formHandler.customAngularSelectHandler,\n      formHandler.defaultHandler,\n      formHandler.fileHandler,\n      formHandler.radioHandler,\n      formHandler.selectHandler,\n      formHandler.uploadedFileHandler,\n    ]\n  ) {}\n\n  public addHandler(handler: FormHandler): void {\n    this.availableHandlers.push(handler);\n  }\n\n  public async handleFill(page: Base, elementName: string, desiredValue: string): Promise<string | void> {\n    const handlers = this.getHandlers();\n\n    for (const handler of handlers) {\n      const isSatisfied = await handler.isSatisfiedBy(page.getElement(elementName), elementName);\n\n      if (isSatisfied) {\n        return handler.handleFill(page, elementName, desiredValue);\n      }\n    }\n\n    return Promise.reject('Could not find matching handler.');\n  }\n\n  public async handleCheck(page: Base, elementName: string, desiredValue: string): Promise<string | void> {\n    const handlers = this.getHandlers();\n\n    for (const handler of handlers) {\n      const isSatisfied = await handler.isSatisfiedBy(page.getElement(elementName), elementName);\n\n      if (isSatisfied) {\n        return handler.handleCheck(page, elementName, desiredValue);\n      }\n    }\n\n    return Promise.reject('Could not find matching handler.');\n  }\n\n  public getHandlers(): FormHandler[] {\n    return this.availableHandlers.sort((handler, otherHandler) => handler.getPriority() - otherHandler.getPriority());\n  }\n}\n\nexport default new FormHandlers();\n"
  },
  {
    "path": "src/form-handlers/index.ts",
    "content": "export { default as fromHandlers } from './handlers';\n"
  },
  {
    "path": "src/generators/generator/index.ts",
    "content": "export * from './string-with-length.generator';\nexport * from './personalData.generator';\n"
  },
  {
    "path": "src/generators/generator/personalData.generator.spec.ts",
    "content": "import { personalDataGenerator } from './personalData.generator';\n\ndescribe('Personal data', () => {\n  it('returns true if is satisfied by', () => {\n    expect(personalDataGenerator.isSatisfiedBy('personalData')).toEqual(true);\n  });\n\n  it('returns false if is not satisfied by', () => {\n    expect(personalDataGenerator.isSatisfiedBy('not-supported-name')).toEqual(false);\n  });\n\n  it('generates a random firstName', done => {\n    personalDataGenerator.generate(['firstName']).then(result => {\n      expect(result.length > 1 && /[A-Z].*/.test(result)).toEqual(true);\n      done();\n    });\n  });\n\n  it('generates a random lastName', done => {\n    personalDataGenerator.generate(['lastName']).then(result => {\n      expect(result.length > 1 && /[A-Z].*/.test(result)).toEqual(true);\n      done();\n    });\n  });\n\n  it('generates a random jobTitle', done => {\n    personalDataGenerator.generate(['jobTitle']).then(result => {\n      expect(result.length > 1).toEqual(true);\n      done();\n    });\n  });\n\n  it('generates a random email', done => {\n    personalDataGenerator.generate(['email']).then(result => {\n      const minEmailLength = 5;\n\n      expect(result.includes('@') && result.length > minEmailLength).toEqual(true);\n      done();\n    });\n  });\n\n  it('return error message - generator is not available', done => {\n    personalDataGenerator.generate(['incorrect']).catch(error => {\n      expect(error === 'Option not available in \"personalData\" generator!').toEqual(true);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/generators/generator/personalData.generator.ts",
    "content": "import * as faker from 'faker';\nimport { Generator } from '../generator.interface';\n\nexport const personalDataGenerator: Generator = {\n  isSatisfiedBy(name) {\n    return name === 'personalData';\n  },\n\n  generate(options) {\n    switch (options[0]) {\n      case 'firstName':\n        return Promise.resolve(faker.name.firstName());\n      case 'lastName':\n        return Promise.resolve(faker.name.lastName());\n      case 'jobTitle':\n        return Promise.resolve(faker.name.jobTitle());\n      case 'email':\n        return Promise.resolve(faker.internet.email(null, null, options[1]));\n      default:\n        return Promise.reject('Option not available in \"personalData\" generator!');\n    }\n  },\n};\n"
  },
  {
    "path": "src/generators/generator/string-with-length.generator.spec.ts",
    "content": "import { stringWithLengthGenerator } from './string-with-length.generator';\n\ndescribe('String with length', () => {\n  it('returns true if is satisfied by', () => {\n    expect(stringWithLengthGenerator.isSatisfiedBy('stringWithLength')).toEqual(true);\n  });\n\n  it('returns false if is not satisfied by', () => {\n    expect(stringWithLengthGenerator.isSatisfiedBy('not-supported-name')).toEqual(false);\n  });\n\n  it('generates string with given length', done => {\n    stringWithLengthGenerator.generate(100).then(result => {\n      expect(result.length).toEqual(100);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/generators/generator/string-with-length.generator.ts",
    "content": "import { Generator } from '../generator.interface';\n\nexport const stringWithLengthGenerator: Generator = {\n  isSatisfiedBy(name) {\n    return name === 'stringWithLength';\n  },\n\n  generate(generatorParam) {\n    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n    const length = parseInt(generatorParam);\n\n    let result = '';\n    for (let i = length; i > 0; i--) {\n      result += chars[Math.floor(Math.random() * chars.length)];\n    }\n\n    return Promise.resolve(result);\n  },\n};\n"
  },
  {
    "path": "src/generators/generator.interface.ts",
    "content": "export interface Generator {\n  isSatisfiedBy(name: string): boolean;\n  generate(...params: any): Promise<any>;\n}\n"
  },
  {
    "path": "src/generators/generators.spec.ts",
    "content": "import { create } from './generators';\n\nconst generators = create();\n\ndescribe('Generators', () => {\n  it('throws an error when no generator was found', () => {\n    expect(() => generators.generate('unknown-generator')).toThrow('Could not find generator for unknown-generator.');\n  });\n\n  it('return generated value', done => {\n    generators.generate('stringWithLength', 100).then(result => {\n      expect(result.length).toEqual(100);\n      done();\n    });\n  });\n\n  it('adds new generator', done => {\n    const customGenerator = {\n      isSatisfiedBy: name => name === 'customGenerator',\n      generate: params => {\n        return Promise.resolve(params);\n      },\n    };\n\n    generators.addGenerator(customGenerator);\n    generators.generate('customGenerator', 'params').then(result => {\n      expect(result).toEqual('params');\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/generators/generators.ts",
    "content": "import * as generators from './generator';\nimport { Generator } from './generator.interface';\n\nexport class Generators {\n  constructor(\n    private availableGenerators: Generator[] = [generators.personalDataGenerator, generators.stringWithLengthGenerator]\n  ) {}\n\n  public generate(generatorName: string, ...params: any): Promise<any> {\n    const gen: Generator = this.findGenerator(generatorName);\n\n    if (gen === undefined) {\n      throw new Error(`Could not find generator for ${generatorName}.`);\n    }\n\n    return gen.generate(...params);\n  }\n\n  public addGenerator(generator: Generator): void {\n    this.availableGenerators.push(generator);\n  }\n\n  public findGenerator(name: string): Generator {\n    return this.availableGenerators.find(gen => gen.isSatisfiedBy(name));\n  }\n}\n\nexport const create = () => new Generators();\n"
  },
  {
    "path": "src/generators/index.ts",
    "content": "import { create } from './generators';\n\nexport { Generators } from './generators';\nexport const generators = create();\n"
  },
  {
    "path": "src/index.ts",
    "content": "// entry file\nimport * as dictionaries from './dictionaries';\nimport * as pages from './pages';\n\nexport { matchers, regexBuilder } from './matchers';\nexport { defineSupportCode, Given, When, Then, After, Before, AfterAll, BeforeAll } from 'cucumber';\nexport { dictionaries } from './dictionaries';\nexport { transformers } from './transformers';\nexport { generators } from './generators';\nexport { default as variableStore } from './web/variable-store.helper';\nexport { default as handlers } from './form-handlers/handlers';\nexport { comparators } from './comparators';\nexport { emailService } from './emails';\nexport { waitForVisibilityOf, waitForInvisibilityOf, waitForCondition } from './web/cucumber/wait-for-condition.helper';\nexport { hookHandlers } from './web/cucumber/hooks/hooks';\n\nexport const BasePage = pages.Form;\nexport const BaseDictionary = dictionaries.Base;\n"
  },
  {
    "path": "src/kakunin.d.ts",
    "content": "declare let browser: any;\ndeclare let by: any;\ndeclare let protractor: any;\n\ndeclare module NodeJS {\n  interface Global {\n    by: any;\n    expect(value: any): any;\n  }\n}\n\ninterface Console {\n  err: any;\n}\n\ndeclare interface RegExpConstructor {\n  escape(text: string): any;\n}\n"
  },
  {
    "path": "src/matchers/index.ts",
    "content": "import { regexBuilder as builder } from './matcher/regex-matcher/regex-builder';\nimport { create as createMatchers } from './matchers';\n\nexport const matchers = createMatchers();\nexport const regexBuilder = builder;\n"
  },
  {
    "path": "src/matchers/matcher/attribute.matcher.spec.ts",
    "content": "import { attributeMatcher } from './attribute.matcher';\n\ndescribe('Attribute matcher', () => {\n  it('is satisfied when the prefix and name are correct', () => {\n    expect(attributeMatcher.isSatisfiedBy('attribute')).toEqual(true);\n  });\n\n  it('is not satisfied when the prefix and name are incorrect', () => {\n    const incorrectParameters = [\n      { prefix: 'f', name: 'incorrect' },\n      { prefix: 'incorrect', name: 'incorrect' },\n      { prefix: 'g', name: 'isVisible' },\n    ];\n\n    incorrectParameters.forEach(parameters => expect(attributeMatcher.isSatisfiedBy(parameters.prefix)).toEqual(false));\n  });\n\n  it('returns true when the attribute is matched', done => {\n    const elementMocked = {\n      getAttribute: () => Promise.resolve('http://some-random-link.com'),\n    };\n\n    attributeMatcher.match(elementMocked, 'href', 'someRandomLinkRegex').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when the attribute is not matched', done => {\n    const elementMocked = {\n      getAttribute: () => Promise.resolve('some-random-link'),\n      locator: () => 'some-locator',\n    };\n\n    attributeMatcher.match(elementMocked, 'href', 'someRandomLinkRegex').catch(err => {\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/attribute.matcher.ts",
    "content": "import { regexBuilder } from './regex-matcher/regex-builder';\nimport { Matcher } from '../matcher.interface';\n\nclass AttributeMatcher implements Matcher {\n  public isSatisfiedBy(prefix) {\n    return prefix === 'attribute';\n  }\n\n  public match(element, attributeName, regexName) {\n    return element.getAttribute(attributeName).then(value => {\n      if (regexBuilder.buildRegex(`r:${regexName}`).test(value)) {\n        return true;\n      }\n\n      const transformedRegexName = `r:${regexName}`;\n      return Promise.reject(`\n        Matcher \"AttributeMatcher\" could not match regex on element \"${element.locator()}\" on attribute \"${attributeName}\". \n        Expected to match: \"${regexBuilder.buildRegex(transformedRegexName).toString()}\", Given: \"${value}\"\n      `);\n    });\n  }\n}\n\nexport const attributeMatcher = new AttributeMatcher();\n"
  },
  {
    "path": "src/matchers/matcher/clickable.matcher.spec.ts",
    "content": "import { clickableMatcher } from './clickable.matcher';\n\ndescribe('Clickable matcher', () => {\n  it('is satisfied when the prefix and the name are correct', () => {\n    expect(clickableMatcher.isSatisfiedBy('f', 'isClickable')).toEqual(true);\n  });\n\n  it('is not satisfied when unsupported parameters are given', () => {\n    const incorrectParameters = [{ prefix: 'r', name: 'isClickable' }, { prefix: 'f', name: 'isNotClickable' }];\n    incorrectParameters.forEach(parameter =>\n      expect(clickableMatcher.isSatisfiedBy(parameter.prefix, parameter.name)).toEqual(false)\n    );\n  });\n\n  it('returns true when the element is clickable', done => {\n    const mockedElement = {\n      getAttribute: attribute => Promise.resolve(null),\n      locator: () => 'some-locator',\n    };\n\n    clickableMatcher.match(mockedElement).then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when the element is not clickable - disabled with disabled parameter', done => {\n    const mockedElement = {\n      getAttribute: attribute => Promise.resolve('disabled'),\n      locator: () => 'some-locator',\n    };\n\n    clickableMatcher.match(mockedElement).catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when the element is not clickable - disabled with true parameter', done => {\n    const mockedElement = {\n      getAttribute: attribute => Promise.resolve(true),\n      locator: () => 'some-locator',\n    };\n\n    clickableMatcher.match(mockedElement).catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when the element is not clickable - disabled with true string parameter', done => {\n    const mockedElement = {\n      getAttribute: attribute => Promise.resolve('true'),\n      locator: () => 'some-locator',\n    };\n\n    clickableMatcher.match(mockedElement).catch(err => {\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/clickable.matcher.ts",
    "content": "import { Matcher } from '../matcher.interface';\n\nclass ClickableMatcher implements Matcher {\n  public isSatisfiedBy(prefix, name) {\n    return prefix === 'f' && name === 'isClickable';\n  }\n\n  public match(element) {\n    return element\n      .getAttribute('disabled')\n      .then(disabled => ['disabled', true, 'true'].indexOf(disabled) === -1)\n      .then(result => {\n        if (result) {\n          return true;\n        }\n\n        return Promise.reject(`\n          Matcher \"ClickableMatcher\" could find attribute disabled on element \"${element.locator()}\".\n        `);\n      });\n  }\n}\n\nexport const clickableMatcher = new ClickableMatcher();\n"
  },
  {
    "path": "src/matchers/matcher/currentDate.matcher.spec.ts",
    "content": "import { currentDateMatcher } from './currentDate.matcher';\nimport * as moment from 'moment';\n\ndescribe('Current Date matcher', () => {\n  it('is satisfied when the prefix and the name are correct', () => {\n    expect(currentDateMatcher.isSatisfiedBy('f', 'currentDate')).toEqual(true);\n  });\n\n  it('is not satisfied when unsupported parameters are given', () => {\n    const incorrectParameters = [{ prefix: 'm', name: 'date' }, { prefix: 't', name: 'currentDate' }];\n    incorrectParameters.forEach(parameter =>\n      expect(currentDateMatcher.isSatisfiedBy(parameter.prefix, parameter.name)).toEqual(false)\n    );\n  });\n\n  it('returns true when the date is matched', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve(moment(new Date())),\n      locator: () => 'some-locator',\n    };\n\n    currentDateMatcher.match(elementMocked).then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when the date with slashes is matched', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve(moment(new Date()).format('MM/DD/YYYY')),\n      locator: () => 'some-locator',\n    };\n\n    currentDateMatcher.match(elementMocked, null, 'MM/DD/YYYY').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when the text date is not matched', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve('Yesterday'),\n      locator: () => 'some-locator',\n    };\n\n    currentDateMatcher.match(elementMocked).catch(err => {\n      done();\n    });\n  });\n  it('returns rejected promise when the date is not matched', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve('1900-01-01'),\n      locator: () => 'some-locator',\n    };\n\n    currentDateMatcher.match(elementMocked).catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when the date is incorrect', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve('1900-01-1900'),\n      locator: () => 'some-locator',\n    };\n\n    currentDateMatcher.match(elementMocked).catch(err => {\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/currentDate.matcher.ts",
    "content": "import * as moment from 'moment';\nimport { Matcher } from '../matcher.interface';\n\nclass CurrentDateMatcher implements Matcher {\n  public isSatisfiedBy(prefix, name) {\n    return prefix === 'f' && name === 'currentDate';\n  }\n\n  public match(element, name = null, params = 'DD-MM-YYYY') {\n    const currentDate = moment(new Date()).format(params);\n    return element.getText().then(text => {\n      const compareDate = moment(new Date(text)).format(params);\n\n      if (compareDate === currentDate) {\n        return true;\n      }\n\n      return Promise.reject(`\n        Matcher \"CurrentDate\" could not match date for element \"${element.locator()}\". Expected: \"${compareDate}\", given: \"${currentDate}\".\n      `);\n    });\n  }\n}\n\nexport const currentDateMatcher = new CurrentDateMatcher();\n"
  },
  {
    "path": "src/matchers/matcher/index.ts",
    "content": "export { clickableMatcher } from './clickable.matcher';\nexport { invisibleMatcher } from './invisible.matcher';\nexport { notClickableMatcher } from './not-clickable.matcher';\nexport { presentMatcher } from './present.matcher';\nexport { textMatcher } from './text.matcher';\nexport { visibleMatcher } from './visible.matcher';\nexport { regexMatcher } from './regex-matcher';\nexport { attributeMatcher } from './attribute.matcher';\nexport { currentDateMatcher } from './currentDate.matcher';\n"
  },
  {
    "path": "src/matchers/matcher/invisible.matcher.spec.ts",
    "content": "import { invisibleMatcher } from './invisible.matcher';\n\ndescribe('Invisible matcher', () => {\n  it('is satisfied when the prefix and the name are correct', () => {\n    expect(invisibleMatcher.isSatisfiedBy('f', 'isNotVisible')).toEqual(true);\n  });\n\n  it('is not satisfied when unsupported parameters are given', () => {\n    const incorrectParameters = [{ prefix: 'f', name: 'isVisible' }, { prefix: 't', name: 'isNotVisible' }];\n    incorrectParameters.forEach(parameter =>\n      expect(invisibleMatcher.isSatisfiedBy(parameter.prefix, parameter.name)).toEqual(false)\n    );\n  });\n\n  it('returns rejected promise when the element is visible', done => {\n    const mockedElement = {\n      isDisplayed: () => Promise.resolve(true),\n      locator: () => 'some-locator',\n    };\n\n    invisibleMatcher.match(mockedElement).catch(() => {\n      done();\n    });\n  });\n\n  it('returns true when the element is not visible', done => {\n    const mockedElement = {\n      isDisplayed: () => Promise.reject(),\n      locator: () => 'some-locator',\n    };\n\n    invisibleMatcher.match(mockedElement).then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/invisible.matcher.ts",
    "content": "import { Matcher } from '../matcher.interface';\n\nclass InvisibleMatcher implements Matcher {\n  public isSatisfiedBy(prefix, name) {\n    return prefix === 'f' && name === 'isNotVisible';\n  }\n\n  public async match(element) {\n    try {\n      await element.isDisplayed();\n      return Promise.reject(`\n        Matcher \"InvisibleMatcher\" could find element \"${element.locator()}\". Expected element to be invisible.\n      `);\n    } catch (err) {\n      return true;\n    }\n  }\n}\n\nexport const invisibleMatcher = new InvisibleMatcher();\n"
  },
  {
    "path": "src/matchers/matcher/not-clickable.matcher.spec.ts",
    "content": "import { notClickableMatcher } from './not-clickable.matcher';\n\ndescribe('Not clickable matcher', () => {\n  it('is satisfied when the prefix and the name are correct', () => {\n    expect(notClickableMatcher.isSatisfiedBy('f', 'isNotClickable')).toEqual(true);\n  });\n\n  it('is not satisfied when unsupported parameters are given', () => {\n    const incorrectParameters = [{ prefix: 'r', name: 'isNotClickable' }, { prefix: 'f', name: 'isClickable' }];\n    incorrectParameters.forEach(parameter =>\n      expect(notClickableMatcher.isSatisfiedBy(parameter.prefix, parameter.name)).toEqual(false)\n    );\n  });\n\n  it('returns rejected promise when the element is clickable', done => {\n    const mockedElement = {\n      getAttribute: attribute => Promise.resolve(null),\n      locator: () => 'some-locator',\n    };\n\n    notClickableMatcher.match(mockedElement).catch(err => {\n      done();\n    });\n  });\n\n  it('returns true when the element is not clickable - disabled with disabled parameter', done => {\n    const mockedElement = {\n      getAttribute: attribute => Promise.resolve('disabled'),\n      locator: () => 'some-locator',\n    };\n\n    notClickableMatcher.match(mockedElement).then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when the element is not clickable - disabled with true parameter', done => {\n    const mockedElement = {\n      getAttribute: attribute => Promise.resolve(true),\n      locator: () => 'some-locator',\n    };\n\n    notClickableMatcher.match(mockedElement).then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when the element is not clickable - disabled with true string parameter', done => {\n    const mockedElement = {\n      getAttribute: attribute => Promise.resolve('true'),\n      locator: () => 'some-locator',\n    };\n\n    notClickableMatcher.match(mockedElement).then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/not-clickable.matcher.ts",
    "content": "import { Matcher } from '../matcher.interface';\n\nclass NotClickableMatcher implements Matcher {\n  public isSatisfiedBy(prefix, name) {\n    return prefix === 'f' && name === 'isNotClickable';\n  }\n\n  public match(element) {\n    return element\n      .getAttribute('disabled')\n      .then(disabled => ['disabled', true, 'true'].indexOf(disabled) !== -1)\n      .then(result => {\n        if (result) {\n          return true;\n        }\n\n        return Promise.reject(`\n          Matcher \"NotClickable\" could not find attribute disabled on element \"${element.locator()}\".\n        `);\n      });\n  }\n}\n\nexport const notClickableMatcher = new NotClickableMatcher();\n"
  },
  {
    "path": "src/matchers/matcher/present.matcher.spec.ts",
    "content": "import { presentMatcher } from './present.matcher';\n\ndescribe('Present matcher', () => {\n  it('is satisfied when the prefix and the name are correct', () => {\n    expect(presentMatcher.isSatisfiedBy('f', 'isPresent')).toEqual(true);\n  });\n\n  it('is not satisfied when unsupported parameters are given', () => {\n    const incorrectParameters = [{ prefix: 'f', name: 'isVisible' }, { prefix: 'r', name: 'isPresent' }];\n\n    incorrectParameters.forEach(parameter =>\n      expect(presentMatcher.isSatisfiedBy(parameter.prefix, parameter.name)).toEqual(false)\n    );\n  });\n\n  it('returns true when the element is present', done => {\n    const mockedElement = {\n      isPresent: () => Promise.resolve(),\n      locator: () => 'some-locator',\n    };\n\n    presentMatcher.match(mockedElement).then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when the element is not present', done => {\n    const mockedElement = {\n      isPresent: () => Promise.reject(),\n      locator: () => 'some-locator',\n    };\n\n    presentMatcher.match(mockedElement).catch(err => {\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/present.matcher.ts",
    "content": "import { Matcher } from '../matcher.interface';\n\nclass PresentMatcher implements Matcher {\n  public isSatisfiedBy(prefix, name) {\n    return prefix === 'f' && name === 'isPresent';\n  }\n\n  public match(element) {\n    return element\n      .isPresent()\n      .then(() => true)\n      .catch(() => Promise.reject(`Matcher \"PresentMatcher\" could not find element \"${element.locator()}\".`));\n  }\n}\n\nexport const presentMatcher = new PresentMatcher();\n"
  },
  {
    "path": "src/matchers/matcher/regex-matcher/index.spec.ts",
    "content": "import { regexMatcher } from '.';\n\ndescribe('Regex matcher', () => {\n  it('is satisfied when the prefix is correct and regex exists', () => {\n    expect(regexMatcher.isSatisfiedBy('r', 'number')).toEqual(true);\n  });\n\n  it('is not satisfied when the prefix is incorrect', () => {\n    expect(regexMatcher.isSatisfiedBy('f', 'number')).toEqual(false);\n  });\n\n  it('is not satisfied when the name is not incorrect', () => {\n    expect(regexMatcher.isSatisfiedBy('r', 'unknown')).toEqual(false);\n  });\n\n  it('returns matches text of element', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve('12345'),\n      getAttribute: name => (name === 'value' ? Promise.resolve('') : Promise.resolve(null)),\n      locator: () => 'some-locator',\n    };\n\n    regexMatcher.match(elementMocked, 'number').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('matches value attribute if text is empty', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve(''),\n      getAttribute: name => (name === 'value' ? Promise.resolve('12345') : Promise.resolve(null)),\n      locator: () => 'some-locator',\n    };\n\n    regexMatcher.match(elementMocked, 'number').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when the text is not matching', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve('not-a-number'),\n      getAttribute: name => (name === 'value' ? Promise.resolve('') : Promise.resolve(null)),\n      locator: () => 'some-locator',\n    };\n\n    regexMatcher.match(elementMocked, 'number').catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when the value attribute is not matched', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve(''),\n      getAttribute: name => (name === 'value' ? Promise.resolve('not-a-number') : Promise.resolve(null)),\n      locator: () => 'some-locator',\n    };\n\n    regexMatcher.match(elementMocked, 'number').catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when the text and attribute are empty', done => {\n    const elementMocked = {\n      getText: () => Promise.resolve(''),\n      getAttribute: () => Promise.resolve(null),\n      locator: () => 'some-locator',\n    };\n\n    regexMatcher.match(elementMocked, 'notEmpty').catch(err => {\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/regex-matcher/index.ts",
    "content": "import regex from './regex';\nimport { regexBuilder } from './regex-builder';\nimport { Matcher } from '../../matcher.interface';\n\nclass RegexMatcher implements Matcher {\n  public isSatisfiedBy(prefix, name) {\n    return prefix === 'r' && typeof regex[name] !== 'undefined';\n  }\n\n  public match(element, regexName) {\n    return element.getText().then(text => {\n      return element.getAttribute('value').then(value => {\n        const regularExpression = regexBuilder.buildRegex(`r:${regexName}`);\n\n        if (text === '') {\n          if (value === null) {\n            return Promise.reject(`\n                  Matcher \"RegexMatcher\" could not match value for element \"${element.locator()}\".\n                  Both text and attribute value are empty.\n                `);\n          }\n\n          if (regularExpression.test(value)) {\n            return true;\n          }\n\n          return Promise.reject(`\n                Matcher \"RegexMatcher\" could not match regex on element \"${element.locator()}\" on value \"${value}\". \n                Expected to match: \"${regularExpression.toString()}\", Given: \"${value}\"\n              `);\n        }\n\n        if (regularExpression.test(text)) {\n          return true;\n        }\n\n        return Promise.reject(`\n              Matcher \"RegexMatcher\" could not match regex on element \"${element.locator()}\" on text \"${text}\". \n              Expected to match: \"${regularExpression.toString()}\", Given: \"${text}\"\n            `);\n      });\n    });\n  }\n}\n\nexport const regexMatcher = new RegexMatcher();\n"
  },
  {
    "path": "src/matchers/matcher/regex-matcher/regex-builder.spec.ts",
    "content": "import { regexBuilder } from './regex-builder';\n\ndescribe('Regex builder', () => {\n  it('throws an error when could not build a regexp', () => {\n    expect(() => regexBuilder.buildRegex('r:unknown-regexp')).toThrow(\n      'Regex with template r:unknown-regexp was not found'\n    );\n  });\n\n  it('returns regular expression object', () => {\n    expect(regexBuilder.buildRegex('r:number')).toEqual(new RegExp('[0-9]+'));\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/regex-matcher/regex-builder.ts",
    "content": "import regex from './regex';\n\nclass RegexBuilder {\n  public buildRegex(regexTemplate: string): RegExp {\n    for (const property in regex) {\n      if (regex.hasOwnProperty(property) && regexTemplate === 'r:' + property) {\n        return new RegExp(regex[property]);\n      }\n    }\n\n    throw new Error('Regex with template ' + regexTemplate + ' was not found');\n  }\n}\n\nexport const regexBuilder = new RegexBuilder();\n"
  },
  {
    "path": "src/matchers/matcher/regex-matcher/regex.ts",
    "content": "import { create } from '../../../core/modules-loader.helper';\nimport { regex } from './regexes/default';\n\nconst modulesLoader = create();\nconst availableRegexes = modulesLoader.getModules('regexes');\n\nconst regularExpressions = availableRegexes.reduce((regexes, newRegexes) => ({ ...regexes, ...newRegexes }), {\n  ...regex,\n});\n\nexport default regularExpressions;\n"
  },
  {
    "path": "src/matchers/matcher/regex-matcher/regexes/default.ts",
    "content": "export const regex = {\n  arabianCharacters: '\\u0621-\\u064A',\n  arabianNumbers: '\\u0660-\\u0669',\n  standardCharacters: 'a-zA-Z',\n  standardNumbers: '0-9',\n  notEmpty: '.+',\n  number: '[0-9]+',\n  pdfFile: '[\\\\w]+.pdf',\n  pdfFileType: 'application/pdf',\n  email:\n    \"[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\",\n  // todo: following regex should be moved to tests/regexes\n  someRandomLinkRegex: '(http(s)?://some-random-link.com)',\n};\n"
  },
  {
    "path": "src/matchers/matcher/text.matcher.spec.ts",
    "content": "import { textMatcher } from './text.matcher';\n\ndescribe('Text matcher', () => {\n  it('is satisfied when the prefix is correct', () => {\n    expect(textMatcher.isSatisfiedBy('t')).toEqual(true);\n  });\n\n  it('is not satisfied when the prefix is incorrect', () => {\n    expect(textMatcher.isSatisfiedBy('r')).toEqual(false);\n  });\n\n  it('returns true when the text is matched - different tag than textarea and input', done => {\n    const elementMocked = {\n      getTagName: () => Promise.resolve('div'),\n      getText: () => Promise.resolve('this string contains message'),\n      locator: () => 'some-locator',\n    };\n\n    textMatcher.match(elementMocked, 'message').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when the text from textarea is matched', done => {\n    const elementMocked = {\n      getTagName: () => Promise.resolve('textarea'),\n      getAttribute: () => Promise.resolve('this string contains message from textarea'),\n      locator: () => 'some-locator',\n    };\n\n    textMatcher.match(elementMocked, 'message from textarea').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when the text from input is matched', done => {\n    const elementMocked = {\n      getTagName: () => Promise.resolve('textarea'),\n      getAttribute: () => Promise.resolve('this string contains message from input'),\n      locator: () => 'some-locator',\n    };\n\n    textMatcher.match(elementMocked, 'message from input').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when the text is not matched - different tag than textarea and input', done => {\n    const elementMocked = {\n      getTagName: () => Promise.resolve('h4'),\n      getText: () => Promise.resolve('missing expected value in string'),\n      locator: () => 'some-locator',\n    };\n\n    textMatcher.match(elementMocked, 'message').catch(err => {\n      expect(err).toEqual(`\n          Matcher \"TextMatcher\" could not match value on element \"some-locator\".\n          Expected: \"message\", Given: \"missing expected value in string\"\n        `);\n      done();\n    });\n  });\n\n  it('returns rejected promise when the text is not matched in input field', done => {\n    const elementMocked = {\n      getTagName: () => Promise.resolve('input'),\n      getAttribute: () => Promise.resolve('missing expected value in input string'),\n      locator: () => 'some-locator',\n    };\n\n    textMatcher.match(elementMocked, 'message').catch(err => {\n      expect(err).toContain('Expected: \"message\", Given: \"missing expected value in input string\"');\n      done();\n    });\n  });\n\n  it('returns rejected promise when the text is not matched in textarea field', done => {\n    const elementMocked = {\n      getTagName: () => Promise.resolve('textarea'),\n      getAttribute: () => Promise.resolve('missing expected value in textarea string'),\n      locator: () => 'some-locator',\n    };\n\n    textMatcher.match(elementMocked, 'message').catch(err => {\n      expect(err).toContain('Matcher \"TextMatcher\" could not match value on element \"some-locator\".');\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/text.matcher.ts",
    "content": "import { separator } from '../matchers';\nimport { Matcher } from '../matcher.interface';\n\nclass TextMatcher implements Matcher {\n  public isSatisfiedBy(prefix) {\n    return prefix === 't';\n  }\n\n  public match(element, ...params) {\n    const expectedValue = params.join(separator);\n\n    return element.getTagName().then(tag => {\n      if (tag === 'input' || tag === 'textarea') {\n        return element.getAttribute('value').then(value => {\n          if (new RegExp(RegExp.escape(expectedValue)).test(value)) {\n            return true;\n          }\n\n          return Promise.reject(`\n            Matcher \"TextMatcher\" could not match value on element \"${element.locator()}\".\n            Expected: \"${expectedValue}\", Given: \"${value}\"\n          `);\n        });\n      }\n\n      return element.getText().then(text => {\n        if (new RegExp(RegExp.escape(expectedValue)).test(text)) {\n          return true;\n        }\n\n        return Promise.reject(`\n          Matcher \"TextMatcher\" could not match value on element \"${element.locator()}\".\n          Expected: \"${expectedValue}\", Given: \"${text}\"\n        `);\n      });\n    });\n  }\n}\n\nexport const textMatcher = new TextMatcher();\n"
  },
  {
    "path": "src/matchers/matcher/visible.matcher.spec.ts",
    "content": "import { visibleMatcher } from './visible.matcher';\n\ndescribe('Visible matcher', () => {\n  it('is satisfied when the prefix and the name are correct', () => {\n    expect(visibleMatcher.isSatisfiedBy('f', 'isVisible')).toEqual(true);\n  });\n\n  it('is not satisfied when unsupported parameters are given', () => {\n    const incorrectParameters = [{ prefix: 'f', name: 'isNotVisible' }, { prefix: 'r', name: 'isVisible' }];\n\n    incorrectParameters.forEach(parameter =>\n      expect(visibleMatcher.isSatisfiedBy(parameter.prefix, parameter.name)).toEqual(false)\n    );\n  });\n\n  it('returns true when the element is visible', done => {\n    const mockedElement = {\n      isDisplayed: () => Promise.resolve(),\n      locator: () => 'some-locator',\n    };\n\n    visibleMatcher.match(mockedElement).then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when the element is not visible', done => {\n    const mockedElement = {\n      isDisplayed: () => Promise.reject(),\n      locator: () => 'some-locator',\n    };\n\n    visibleMatcher.match(mockedElement).catch(err => {\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matcher/visible.matcher.ts",
    "content": "import { Matcher } from '../matcher.interface';\n\nclass VisibleMatcher implements Matcher {\n  public isSatisfiedBy(prefix, name) {\n    return prefix === 'f' && name === 'isVisible';\n  }\n\n  public match(element) {\n    return element\n      .isDisplayed()\n      .then(() => true)\n      .catch(() => {\n        return Promise.reject(`Matcher \"VisibleMatcher\" could not find element \"${element.locator()}\".`);\n      });\n  }\n}\n\nexport const visibleMatcher = new VisibleMatcher();\n"
  },
  {
    "path": "src/matchers/matcher.interface.ts",
    "content": "export interface Matcher {\n  isSatisfiedBy(prefix: string, name?: string): boolean;\n  match(element: object, param1?: string, param2?: string): Promise<string | boolean>;\n}\n"
  },
  {
    "path": "src/matchers/matchers.spec.ts",
    "content": "import { create } from './matchers';\n\nconst matchers = create();\n\ndescribe('Matchers', () => {\n  it('throws an error when no matcher was found', () => {\n    const mockedElement = {};\n\n    expect(() => matchers.match(mockedElement, 'incorrect:unknown-matcher')).toThrow(\n      'Could not find matcher for incorrect:unknown-matcher.'\n    );\n  });\n\n  it('returns true when found a matcher and element value is correct', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('div'),\n      getText: () => Promise.resolve('my message'),\n    };\n\n    matchers.match(mockedElement, 't:message').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when found a matcher and element value in input field is correct', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('input'),\n      getAttribute: () => Promise.resolve('my message'),\n    };\n\n    matchers.match(mockedElement, 't:message').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when found a matcher and element value in textarea field is correct', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('textarea'),\n      getAttribute: () => Promise.resolve('my message'),\n    };\n\n    matchers.match(mockedElement, 't:message').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when found a matcher and element value is not correct', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('h2'),\n      getText: () => Promise.resolve('my message'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:not-existing').catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when found a matcher and element value in input field is not correct', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('input'),\n      getAttribute: () => Promise.resolve('my message'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:not-existing').catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when found a matcher and element value in textarea field is not correct', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('textarea'),\n      getAttribute: () => Promise.resolve('my message'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:not-existing').catch(err => {\n      done();\n    });\n  });\n\n  it('returns true when found a matcher and element value after a first colon sign is correct', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('p'),\n      getText: () => Promise.resolve('my message: contains :colons'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:contains :colons').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when found a matcher and element value after a first colon sign is correct - input field of the element', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('input'),\n      getAttribute: () => Promise.resolve('my message: contains :colons'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:contains :colons').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns true when found a matcher and element value after a first colon sign is correct - textarea field of the element', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('textarea'),\n      getAttribute: () => Promise.resolve('my message: contains :colons'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:contains :colons').then(result => {\n      expect(result).toEqual(true);\n      done();\n    });\n  });\n\n  it('returns rejected promise when found a matcher but a text after colon sign is incorrect', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('td'),\n      getText: () => Promise.resolve('my message: contains :colons'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:my message: contains :incorrect').catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when found a matcher but a text after colon sign is incorrect - input field of the element', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('input'),\n      getAttribute: () => Promise.resolve('my message: contains :colons'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:my message: contains :incorrect').catch(err => {\n      done();\n    });\n  });\n\n  it('returns rejected promise when found a matcher but a text after colon sign is incorrect - textarea field of the element', done => {\n    const mockedElement = {\n      getTagName: () => Promise.resolve('textarea'),\n      getAttribute: () => Promise.resolve('my message: contains :colons'),\n      locator: () => 'some-locator',\n    };\n\n    matchers.match(mockedElement, 't:my message: contains :incorrect').catch(err => {\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "src/matchers/matchers.ts",
    "content": "import * as matchers from './matcher';\nimport { Matcher } from './matcher.interface';\n\nexport const separator = ':';\n\nclass Matchers {\n  constructor(\n    private availableMatchers: Matcher[] = [\n      matchers.regexMatcher,\n      matchers.clickableMatcher,\n      matchers.invisibleMatcher,\n      matchers.notClickableMatcher,\n      matchers.presentMatcher,\n      matchers.textMatcher,\n      matchers.visibleMatcher,\n      matchers.attributeMatcher,\n      matchers.currentDateMatcher,\n    ]\n  ) {}\n\n  public addMatcher(matcher: Matcher): void {\n    this.availableMatchers.push(matcher);\n  }\n\n  public match(element: object, matcherName: string): Promise<string | boolean> {\n    const splittedValue = matcherName.split(separator);\n    const matcher = this.findMatcher(splittedValue[0], splittedValue[1]);\n\n    if (matcher === undefined) {\n      throw new Error(`Could not find matcher for ${matcherName}.`);\n    }\n\n    return matcher.match(element, ...splittedValue.slice(1));\n  }\n\n  public findMatcher(prefix: string, param: string): Matcher {\n    return this.availableMatchers.find(matcher => matcher.isSatisfiedBy(prefix, param));\n  }\n}\n\nexport const create = () => new Matchers();\n"
  },
  {
    "path": "src/pages/base.ts",
    "content": "import config from '../core/config.helper';\nimport { waitForInvisibilityOf, waitForVisibilityOf } from '../web/cucumber/wait-for-condition.helper';\nimport { isRelativePage, waitForUrlChangeTo } from '../web/url-parser.helper';\nimport { stringify } from 'querystring';\nimport { element } from 'protractor';\n\nclass Page {\n  private url: string;\n\n  public visit() {\n    if (config.type === 'otherWeb' || !isRelativePage(this.url)) {\n      protractor.browser.ignoreSynchronization = true;\n\n      return protractor.browser.get(this.url);\n    }\n\n    return protractor.browser.get(this.url).then(() => protractor.browser.waitForAngular());\n  }\n\n  public visitWithParameters(data) {\n    const additionalParams: any = [];\n\n    const url =\n      data.raw().reduce((prev, item) => {\n        if (prev.indexOf(`:${item[0]}`) === -1) {\n          additionalParams[item[0]] = item[1];\n          return prev;\n        }\n        return prev.replace(`:${item[0]}`, item[1]);\n      }, this.url) + (Object.entries(additionalParams).length > 0 ? '?' + stringify(additionalParams) : '');\n\n    if (config.type === 'otherWeb' || !isRelativePage(url)) {\n      protractor.browser.ignoreSynchronization = true;\n\n      return protractor.browser.get(url);\n    }\n\n    return protractor.browser.get(url).then(() => protractor.browser.waitForAngular());\n  }\n\n  public async isOn() {\n    if (isRelativePage(this.url) && config.type !== 'otherWeb') {\n      protractor.browser.ignoreSynchronization = false;\n    }\n\n    return browser.wait(async () => {\n      const currentUrl = await browser.getCurrentUrl().then(url => url);\n\n      return waitForUrlChangeTo(this.url, currentUrl)(config.baseUrl);\n    }, config.waitForPageTimeout * 1000);\n  }\n\n  public click(elementName: string) {\n    return this.getElement(elementName).click();\n  }\n\n  public isDisabled(elementName: string) {\n    return this.getElement(elementName)\n      .getAttribute('disabled')\n      .then(disabled => ['disabled', true, 'true'].indexOf(disabled) !== -1);\n  }\n\n  public isVisible(elementName: string) {\n    return this.getElement(elementName).isDisplayed();\n  }\n\n  public isPresent(elementName: string) {\n    return this.getElement(elementName).isPresent();\n  }\n\n  public getNumberOfElements(elementName: string) {\n    return this.getElements(elementName).count();\n  }\n\n  public scrollIntoElement(elementName: string, elementIndex?: string) {\n    if (elementIndex !== undefined) {\n      return browser.executeScript(\n        'arguments[0].scrollIntoView(false);',\n        this.getElement(elementName)\n          .get(elementIndex)\n          .getWebElement()\n      );\n    }\n\n    return browser.executeScript('arguments[0].scrollIntoView(false);', this.getElement(elementName).getWebElement());\n  }\n\n  public waitForVisibilityOf(elementName: string) {\n    return waitForVisibilityOf(this.getElement(elementName));\n  }\n\n  public waitForInvisibilityOf(elementName: string) {\n    return waitForInvisibilityOf(this.getElement(elementName));\n  }\n\n  public getElement(elementName: string) {\n    if (!this[elementName]) {\n      return element(by.css(elementName));\n    }\n\n    return this[elementName];\n  }\n\n  public getElements(elementName: string) {\n    if (!this[elementName]) {\n      return element.all(by.css(elementName));\n    }\n\n    return this[elementName];\n  }\n}\n\nexport default Page;\n"
  },
  {
    "path": "src/pages/form.ts",
    "content": "import { fromHandlers } from '../form-handlers';\nimport { transformers } from '../transformers';\nimport Base from './base';\n\nclass FormPage extends Base {\n  public async fillForm(formData) {\n    for (const item of formData) {\n      await this.fillField(item[0], item[1]);\n    }\n\n    return Promise.resolve();\n  }\n\n  public async checkForm(formData) {\n    for (const item of formData) {\n      await this.checkField(item[0], item[1]);\n    }\n\n    return Promise.resolve();\n  }\n\n  public fillField(name, value) {\n    return fromHandlers.handleFill(this, name, transformers.transform(value));\n  }\n\n  public checkField(name, value) {\n    return fromHandlers.handleCheck(this, name, transformers.transform(value));\n  }\n}\n\nexport default FormPage;\n"
  },
  {
    "path": "src/pages/index.ts",
    "content": "import BasePage from './base';\nimport FormPage from './form';\n\nexport const Base = BasePage;\nexport const Form = FormPage;\n"
  },
  {
    "path": "src/protractor.conf.ts",
    "content": "require('./core/prototypes');\nimport * as jestExpect from 'expect';\nimport * as path from 'path';\nimport config from './core/config.helper';\nimport { deleteReports } from './core/fs/delete-files.helper';\nimport { prepareCatalogs } from './core/fs/prepare-catalogs.helper';\nimport { browsersConfiguration, setSeleniumAddress } from './web/browsers/browsers-config.helper';\nimport { getBrowsersDrivers } from './web/browsers/get-browser-drivers.helper';\nimport { connectBrowserstack, disconnectBrowserstack } from './web/browsers/browserstack-config.helper';\nimport { emailService } from './emails';\nconst commandArgs = require('minimist')(process.argv.slice(2));\nconst modulesLoader = require('./core/modules-loader.helper.js').create();\n\nconst reportsDirectory = path.join(config.projectPath, config.reports);\nconst jsonOutputDirectory = path.join(reportsDirectory, 'json-output-folder');\nconst generatedReportsDirectory = path.join(reportsDirectory, 'report');\nconst featureReportsDirectory = path.join(generatedReportsDirectory, 'features');\nconst performanceReportsDirectory = path.join(reportsDirectory, 'performance');\n\nconst prepareReportCatalogs = () => {\n  prepareCatalogs(reportsDirectory);\n  prepareCatalogs(jsonOutputDirectory);\n  prepareCatalogs(generatedReportsDirectory);\n  prepareCatalogs(featureReportsDirectory);\n  prepareCatalogs(performanceReportsDirectory);\n};\n\nconst deleteReportFiles = () => {\n  deleteReports(reportsDirectory);\n  deleteReports(jsonOutputDirectory);\n  deleteReports(generatedReportsDirectory);\n  deleteReports(featureReportsDirectory);\n  deleteReports(performanceReportsDirectory);\n\n  console.log('All reports have been deleted!');\n};\n\nconst configureMultiCapabilities = () => browsersConfiguration(config, commandArgs);\n\nexports.config = {\n  seleniumAddress: setSeleniumAddress(commandArgs, config),\n  getMultiCapabilities: configureMultiCapabilities(),\n  jvmArgs: getBrowsersDrivers(commandArgs),\n\n  useAllAngular2AppRoots: config.type === 'ng2',\n\n  getPageTimeout: parseInt(config.timeout) * 1000,\n  allScriptsTimeout: parseInt(config.timeout) * 1000,\n\n  framework: 'custom',\n  frameworkPath: require.resolve('protractor-cucumber-framework'),\n  specs: [],\n\n  cucumberOpts: {\n    require: [\n      './web/cucumber/config.js',\n      './step_definitions/**/*.js',\n      './web/cucumber/hooks.js',\n      ...config.step_definitions.map(file => path.join(config.projectPath, file, '**/*.js')),\n    ],\n    format: [`json:${process.cwd()}/${config.reports}/features-report.json`],\n    profile: false,\n    'no-source': true,\n  },\n\n  plugins: [\n    {\n      package: 'protractor-multiple-cucumber-html-reporter-plugin',\n      options: {\n        removeExistingJsonReportFile: true,\n        removeOriginalJsonReportFile: true,\n        automaticallyGenerateReport: true,\n        saveCollectedJSON: true,\n      },\n    },\n  ],\n\n  async beforeLaunch() {\n    prepareReportCatalogs();\n    deleteReportFiles();\n\n    if (commandArgs.browserstack) {\n      await connectBrowserstack((await configureMultiCapabilities()())[0]['browserstack.key']);\n    }\n  },\n\n  async afterLaunch() {\n    await disconnectBrowserstack(commandArgs.browserstack);\n  },\n\n  onPrepare() {\n    if (!config.headless) {\n      browser.driver\n        .manage()\n        .window()\n        .setSize(parseInt(config.browserWidth), parseInt(config.browserHeight));\n    }\n\n    modulesLoader.getModules('matchers');\n    modulesLoader.getModules('dictionaries');\n    modulesLoader.getModules('generators');\n    modulesLoader.getModules('comparators');\n    modulesLoader.getModules('form_handlers');\n    modulesLoader.getModules('transformers');\n    modulesLoader.getModules('emails');\n    modulesLoader.getModules('hooks');\n\n    const modules = modulesLoader.getModulesAsObject(config.pages.map(page => path.join(config.projectPath, page)));\n\n    browser.page = Object.keys(modules).reduce(\n      (pages, moduleName) => ({ ...pages, [moduleName]: new modules[moduleName]() }),\n      {}\n    );\n\n    global.expect = jestExpect;\n\n    if (config.clearEmailInboxBeforeTests) {\n      return emailService.clearInbox();\n    }\n  },\n\n  baseUrl: config.baseUrl,\n};\n"
  },
  {
    "path": "src/rest/api-request.ts",
    "content": "import { Headers } from 'node-fetch';\nimport FormData = require('form-data');\n\ninterface HeaderList {\n  [name: string]: string;\n}\n\nexport class ApiRequest {\n  public method: string;\n  public endpoint: string;\n  private payload: string | object;\n  private headers: Headers;\n  private formData: FormData;\n\n  constructor() {\n    this.payload = null;\n    this.headers = new Headers();\n    this.formData = new FormData();\n  }\n\n  public addHeaders(headers: HeaderList) {\n    for (const [key, value] of Object.entries(headers)) {\n      this.headers.append(key, value);\n    }\n  }\n\n  public addFormData(payload) {\n    for (const table of payload) {\n      this.formData.append(table[0], table[1]);\n    }\n    return this.formData;\n  }\n\n  get body() {\n    return this.payload;\n  }\n\n  set body(payload) {\n    if (payload instanceof FormData) {\n      this.payload = payload;\n    } else {\n      this.payload = payload ? JSON.stringify(payload) : undefined;\n    }\n  }\n}\n"
  },
  {
    "path": "src/rest/api-response.spec.ts",
    "content": "import { ApiResponse } from './api-response';\n\nconst response = new ApiResponse(200, { type: 'Fiat', model: '500', color: 'white' });\n\ndescribe('apiResponse', () => {\n  it('returns true when statuses are the same', () => {\n    expect(response.hasStatus(200)).toEqual(true);\n  });\n\n  it('returns false when statuses are different', () => {\n    expect(response.hasStatus(100)).toEqual(false);\n  });\n\n  it('returns true when response match given object', () => {\n    expect(\n      response.hasBodyMatch({\n        type: 'Fiat',\n        model: '500',\n        color: 'white',\n      })\n    ).toEqual(true);\n  });\n\n  it('returns false when response doesnt match given object', () => {\n    expect(\n      response.hasBodyMatch({\n        model: '500',\n        color: 'white',\n      })\n    ).toEqual(false);\n  });\n});\n"
  },
  {
    "path": "src/rest/api-response.ts",
    "content": "import * as _ from 'lodash';\nimport Ajv from 'ajv';\nconst ajv = new Ajv({ allErrors: true });\n\nexport class ApiResponse {\n  private readonly body: object;\n  private readonly status: number;\n\n  constructor(responseStatus, body) {\n    this.body = body;\n    this.status = responseStatus;\n  }\n\n  public hasStatus(status) {\n    return this.status === status;\n  }\n\n  public hasBodyMatch(body) {\n    if (Object.keys(this.body).length === 0) {\n      return Error('Response from server was empty');\n    }\n    return _.isEqual(this.body, body);\n  }\n\n  public hasMatchingSchema(schema) {\n    const test = ajv.compile(schema);\n    const isValid = test(this.body);\n\n    if (isValid === false) {\n      throw Error('Response doesnt match schema');\n    }\n  }\n}\n"
  },
  {
    "path": "src/rest/rest-api-service.ts",
    "content": "import fetch from 'node-fetch';\nimport { ApiResponse } from './api-response';\n\nexport class RestApiService {\n  private readonly baseUrl: string;\n\n  constructor(baseUrl) {\n    this.baseUrl = baseUrl;\n  }\n\n  public fetch(request) {\n    const url = this.resolveUrl(request.endpoint);\n\n    return fetch(url, { method: request.method, body: request.body, headers: request.headers }).then(response => {\n      const contentType = response.headers.get('content-type');\n      if (contentType && contentType.startsWith('application/json')) {\n        return response.json().then(requestBody => {\n          return new ApiResponse(response.status, requestBody);\n        });\n      }\n      return new ApiResponse(response.status, {});\n    });\n  }\n\n  private resolveUrl(endpoint) {\n    return `${this.baseUrl}${endpoint}`;\n  }\n}\n"
  },
  {
    "path": "src/step_definitions/api.ts",
    "content": "import { defineSupportCode } from 'cucumber';\nimport config from '../core/config.helper';\nimport { RestApiService } from '../rest/rest-api-service';\nimport { ApiRequest } from '../rest/api-request';\n\nconst service = new RestApiService(config.apiUrl);\nlet apiRequest = new ApiRequest();\n\ndefineSupportCode(({ When, Then }) => {\n  let fetchResult;\n\n  When(/^I send \"([^\"]*)\" request on \"([^\"]*)\" endpoint$/, (method, endpoint) => {\n    apiRequest.method = method;\n    apiRequest.endpoint = endpoint;\n    return service\n      .fetch(apiRequest)\n      .then(response => {\n        fetchResult = response;\n        return response;\n      })\n      .finally(() => {\n        apiRequest = new ApiRequest();\n        return apiRequest;\n      });\n  });\n\n  When(/^I send \"([^\"]*)\" request on \"([^\"]*)\" endpoint with JSON body:$/, (method, endpoint, payload) => {\n    apiRequest.method = method;\n    apiRequest.endpoint = endpoint;\n    apiRequest.body = JSON.parse(payload);\n    apiRequest.addHeaders({ 'Content-Type': 'application/json' });\n\n    return service\n      .fetch(apiRequest)\n      .then(response => {\n        fetchResult = response;\n        return response;\n      })\n      .finally(() => {\n        apiRequest = new ApiRequest();\n        return apiRequest;\n      });\n  });\n\n  When(/^I send \"([^\"]*)\" request on \"([^\"]*)\" endpoint using form data:$/, (method, endpoint, payload) => {\n    apiRequest.method = method;\n    apiRequest.endpoint = endpoint;\n    apiRequest.body = apiRequest.addFormData(payload.raw());\n    apiRequest.addHeaders({ 'Content-Type': 'multipart/form-data' });\n\n    return service\n      .fetch(apiRequest)\n      .then(response => {\n        fetchResult = response;\n        return response;\n      })\n      .finally(() => {\n        apiRequest = new ApiRequest();\n        return apiRequest;\n      });\n  });\n\n  When(/^I set request headers:$/, headers => {\n    return apiRequest.addHeaders(headers.rowsHash());\n  });\n\n  Then(/^the response code should be \"([^\"]*)\"$/, status => {\n    return expect(fetchResult.hasStatus(parseInt(status))).toBe(true);\n  });\n\n  Then(/^the response should exact match to body:$/, body => {\n    return expect(fetchResult.hasBodyMatch(JSON.parse(body))).toBe(true);\n  });\n\n  Then(/^the response should match JSON schema:$/, schema => {\n    try {\n      fetchResult.hasMatchingSchema(JSON.parse(schema));\n    } catch (error) {\n      return Promise.reject(error);\n    }\n  });\n});\n"
  },
  {
    "path": "src/step_definitions/debug.ts",
    "content": "import { Then } from 'cucumber';\n\nThen(/^I wait for \"([^\"]*)\" seconds$/, seconds => {\n  return browser.sleep(Number(seconds) * 1000);\n});\n"
  },
  {
    "path": "src/step_definitions/elements.ts",
    "content": "import * as chai from 'chai';\nimport { When, Then } from 'cucumber';\nimport { comparators } from '../comparators';\nimport config from '../core/config.helper';\nimport { matchers, regexBuilder } from '../matchers';\nimport { waitForCondition } from '../web/cucumber/wait-for-condition.helper';\nimport variableStore from '../web/variable-store.helper';\n\nconst timeout = parseInt(config.elementsVisibilityTimeout) * 1000;\n\nconst handlePromises = (hashedData, onSuccess, onReject) => resolvedPromises => {\n  for (let i = 0; i < resolvedPromises.length; i += hashedData.length) {\n    let allFieldsMatching = true;\n\n    for (let j = i; j < i + hashedData.length; j++) {\n      if (resolvedPromises[j] === false) {\n        allFieldsMatching = false;\n        break;\n      }\n    }\n\n    if (allFieldsMatching) {\n      return onSuccess();\n    }\n  }\n\n  return onReject();\n};\n\nfunction checkNumberOfElements(numberExpression, element) {\n  const self = this;\n  const numberPattern = /\\d+/g;\n  const numbers = numberExpression.match(numberPattern).map(item => parseInt(item));\n\n  const expectFunction = async (words, num) => {\n    const numberOfElements = await self.currentPage.getNumberOfElements(element);\n    return chai.expect(numberOfElements).to.be[words.pop()](...num);\n  };\n\n  return expectFunction(numberExpression.substr(0, numberExpression.indexOf(numbers[0]) - 1).split(' '), numbers);\n}\n\nWhen(/^I wait for \"([^\"]*)\" of the \"([^\"]*)\" element$/, function(condition, elementName) {\n  if (this.currentPage.getElement(elementName) instanceof protractor.ElementArrayFinder) {\n    return waitForCondition(condition, timeout)(this.currentPage.getElement(elementName).first());\n  }\n\n  return waitForCondition(condition, timeout)(this.currentPage.getElement(elementName));\n});\n\nWhen(/^I scroll to the \"([^\"]*)\" element$/, function(elementName) {\n  return this.currentPage.scrollIntoElement(elementName);\n});\n\nWhen(/^I click the \"([^\"]*)\" element$/, function(elementName) {\n  return this.currentPage\n    .scrollIntoElement(elementName)\n    .catch(() => Promise.resolve())\n    .then(() => this.currentPage.waitForVisibilityOf(elementName))\n    .then(() => this.currentPage.scrollIntoElement(elementName))\n    .then(() => this.currentPage.click(elementName))\n    .catch(() => {\n      return waitForCondition('elementToBeClickable', timeout)(this.currentPage.getElement(elementName)).then(() => {\n        return this.currentPage.click(elementName);\n      });\n    })\n    .catch(() => {\n      console.warn('Warning! Element was not clickable. We need to scroll it down.');\n      return browser\n        .executeScript('window.scrollBy(0,50);')\n        .then(() => this.currentPage.waitForVisibilityOf(elementName))\n        .then(() => this.currentPage.click(elementName));\n    })\n    .catch(() => {\n      console.warn('Warning! Element was not clickable. We need use the WebDriver method to perform the click action.');\n      return browser\n        .actions()\n        .mouseMove(this.currentPage.getElement(elementName))\n        .mouseMove({ x: 5, y: 0 })\n        .click()\n        .perform();\n    })\n    .catch(() => {\n      return Promise.reject(`Error, after scrolling the element \"${elementName}\" is still not clickable.`);\n    });\n});\n\nWhen(/^I store the \"([^\"]*)\" element text as \"([^\"]*)\" variable$/, function(elementName, variable) {\n  return this.currentPage.waitForVisibilityOf(elementName).then(async () => {\n    const elementTag = await this.currentPage[elementName].getTagName(tag => tag);\n\n    if (elementTag === 'input' || elementTag === 'textarea') {\n      return this.currentPage\n        .getElement(elementName)\n        .getAttribute('value')\n        .then(value => {\n          variableStore.storeVariable(variable, value);\n        });\n    }\n\n    return this.currentPage\n      .getElement(elementName)\n      .getText()\n      .then(text => {\n        variableStore.storeVariable(variable, text);\n      });\n  });\n});\n\nWhen(/^I update the \"([^\"]*)\" element text as \"([^\"]*)\" variable$/, function(elementName, variable) {\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    this.currentPage\n      .getElement(elementName)\n      .getText()\n      .then(text => {\n        variableStore.updateVariable(variable, text);\n      });\n  });\n});\n\nWhen(/^I store the \"([^\"]*)\" element text matched by \"([^\"]*)\" as \"([^\"]*)\" variable$/, function(\n  elementName,\n  matcher,\n  variable\n) {\n  const regex = regexBuilder.buildRegex(matcher);\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    return this.currentPage\n      .getElement(elementName)\n      .getText()\n      .then(text => {\n        const matchedText = text.match(regex);\n\n        if (matchedText === null) {\n          return Promise.reject(`Could not match text ${text} with matcher ${matcher}`);\n        }\n\n        if (matchedText.length <= 1) {\n          return Promise.reject(`Matcher ${matcher} does not contain capturing brackets`);\n        }\n\n        variableStore.storeVariable(variable, matchedText[1]);\n      });\n  });\n});\n\nWhen(/^I wait for the \"([^\"]*)\" element to disappear$/, function(elementName, sync) {\n  const self = this;\n  let maxRepeats = 10;\n\n  const interval = setInterval(() => {\n    console.log('Waiting for element to disappear...');\n\n    return self.currentPage.isPresent(elementName).then(isPresent => {\n      if (!isPresent) {\n        clearInterval(interval);\n        sync();\n        return;\n      }\n\n      maxRepeats--;\n\n      if (maxRepeats === 0) {\n        clearInterval(interval);\n        sync('Element is still visible');\n      }\n    });\n  }, 1500);\n});\n\nThen(/^the \"([^\"]*)\" element is visible$/, function(elementName) {\n  return this.currentPage.isVisible(elementName);\n});\n\nThen(/^the \"([^\"]*)\" element is not visible$/, function(elementName) {\n  return this.currentPage\n    .isVisible(elementName)\n    .then(isVisible => Promise.reject(isVisible))\n    .catch(isVisible => {\n      if (isVisible === true) {\n        return Promise.reject(`Element '${elementName}' should not be visible.`);\n      }\n\n      return Promise.resolve();\n    });\n});\n\nThen(/^the \"([^\"]*)\" element is disabled$/, async function(elementName) {\n  return await expect(this.currentPage.isDisabled(elementName)).resolves.toBe(true);\n});\n\nWhen(/^I store table \"([^\"]*)\" rows as \"([^\"]*)\" with columns:$/, function(table, variableName, data) {\n  const self = this;\n  const columns = data.raw().map(element => element[0]);\n  const promises = [];\n  return this.currentPage.waitForVisibilityOf(table).then(() => {\n    return this.currentPage\n      .getElement(table)\n      .each(element => {\n        const rowPromises = [];\n\n        for (const columnIndex in columns) {\n          if (columns.hasOwnProperty(columnIndex)) {\n            rowPromises.push(element.element(self.currentPage.getElement(columns[columnIndex]).locator()).getText());\n          }\n        }\n\n        promises.push(Promise.all(rowPromises));\n      })\n      .then(() =>\n        Promise.all(promises).then(resolvedPromises => {\n          variableStore.storeVariable(variableName, resolvedPromises);\n        })\n      );\n  });\n});\n\nThen(/^there are following elements in table \"([^\"]*)\":$/, function(table, data) {\n  const self = this;\n  const allElements = this.currentPage.getElements(table);\n  const hashes = data.hashes();\n  return this.currentPage.waitForVisibilityOf(table).then(() => {\n    return checkNumberOfElements.call(this, `equal ${hashes.length}`, table).then(() => {\n      const promises = [];\n\n      return allElements\n        .each((element, index) => {\n          const hash = hashes[index];\n\n          for (const prop in hash) {\n            if (hash.hasOwnProperty(prop)) {\n              const propValue = hash[prop];\n\n              promises.push(\n                matchers.match(\n                  element.element(self.currentPage.getElement(prop).locator()),\n                  variableStore.replaceTextVariables(propValue)\n                )\n              );\n            }\n          }\n        })\n        .then(() => Promise.all(promises));\n    });\n  });\n});\n\nThen(/^there are \"([^\"]*)\" following elements for element \"([^\"]*)\":$/, function(numberExpression, elementName, data) {\n  const self = this;\n  const allElements = this.currentPage.getElements(elementName);\n  const hashedData = data.raw();\n\n  if (hashedData.length === 0) {\n    return Promise.reject('Missing table under the step.');\n  }\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    return checkNumberOfElements.call(this, numberExpression, elementName).then(() => {\n      const promises = [];\n\n      return allElements\n        .each(element => {\n          hashedData.forEach(hash => {\n            promises.push(\n              matchers.match(\n                element.element(self.currentPage.getElement(hash[0]).locator()),\n                variableStore.replaceTextVariables(hash[1])\n              )\n            );\n          });\n        })\n        .then(() => Promise.all(promises));\n    });\n  });\n});\n\nThen(/^there are \"([^\"]*)\" dropdown list elements with following options:$/, function(elementName, data) {\n  const allOptionElements = this.currentPage.getElement(elementName);\n  const hashedData = data.raw();\n\n  if (hashedData.length === 0) {\n    return Promise.reject('Missing table under the step.');\n  }\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    allOptionElements.getText().then(textArray => {\n      if (textArray.length === hashedData.length) {\n        hashedData.forEach(hash => {\n          textArray.splice(textArray.indexOf(hash), 1);\n        });\n      } else {\n        return Promise.reject(\"Number of options doesn't match the number of asked\");\n      }\n      expect(textArray.length).toEqual(0);\n    });\n  });\n});\n\nThen(/^there is element \"([^\"]*)\" with value \"([^\"]*)\"$/, function(elementName, value) {\n  const pageElement = this.currentPage.getElement(elementName);\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    return matchers\n      .match(pageElement, variableStore.replaceTextVariables(value))\n      .then(matcherResult => expect(matcherResult).toBe(true));\n  });\n});\n\nThen(/^there is no element \"([^\"]*)\" with value \"([^\"]*)\"$/, function(elementName, value) {\n  const pageElement = this.currentPage.getElement(elementName);\n\n  return matchers\n    .match(pageElement, variableStore.replaceTextVariables(value))\n    .catch(() => Promise.resolve(false))\n    .then(result => (result ? Promise.reject() : Promise.resolve()));\n});\n\nThen(/^there is element \"([^\"]*)\" containing \"([^\"]*)\" text$/, function(elementName, value) {\n  const pageElement = this.currentPage.getElement(elementName);\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    return matchers.match(pageElement, variableStore.replaceTextVariables(`t:${value}`));\n  });\n});\n\nThen(/^there is no element \"([^\"]*)\" containing \"([^\"]*)\" text$/, function(elementName, value) {\n  const pageElement = this.currentPage.getElement(elementName);\n\n  return matchers\n    .match(pageElement, variableStore.replaceTextVariables(`t:${value}`))\n    .catch(() => Promise.resolve(false))\n    .then(result => (result ? Promise.reject() : Promise.resolve()));\n});\n\nThen(/^there is element \"([^\"]*)\" matching \"([^\"]*)\" matcher$/, function(elementName, matcher) {\n  const pageElement = this.currentPage.getElement(elementName);\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    return matchers\n      .match(pageElement, variableStore.replaceTextVariables(`f:${matcher}`))\n      .then(matcherResult => expect(matcherResult).toBe(true));\n  });\n});\n\nThen(/^there is no element \"([^\"]*)\" matching \"([^\"]*)\" matcher$/, function(elementName, matcher) {\n  const pageElement = this.currentPage.getElement(elementName);\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    return matchers\n      .match(pageElement, variableStore.replaceTextVariables(`f:${matcher}`))\n      .catch(() => Promise.resolve(false))\n      .then(result => (result ? Promise.reject() : Promise.resolve()));\n  });\n});\n\nThen(/^there is element \"([^\"]*)\" with \"([^\"]*)\" regex$/, function(elementName, matcher) {\n  const pageElement = this.currentPage.getElement(elementName);\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    return matchers\n      .match(pageElement, variableStore.replaceTextVariables(`r:${matcher}`))\n      .then(matcherResult => expect(matcherResult).toBe(true));\n  });\n});\n\nThen(/^there is no element \"([^\"]*)\" with \"([^\"]*)\" regex$/, function(elementName, matcher) {\n  const pageElement = this.currentPage.getElement(elementName);\n\n  return this.currentPage.waitForVisibilityOf(elementName).then(() => {\n    return matchers\n      .match(pageElement, variableStore.replaceTextVariables(`r:${matcher}`))\n      .catch(() => Promise.resolve(false))\n      .then(result => (result ? Promise.reject() : Promise.resolve()));\n  });\n});\n\nThen(/^there are \"([^\"]*)\" \"([^\"]*)\" elements$/, checkNumberOfElements);\n\nThen(/^every \"([^\"]*)\" element should have the same value for element \"([^\"]*)\"$/, function(\n  containerName,\n  elementName\n) {\n  const self = this;\n  return this.currentPage.waitForVisibilityOf(containerName).then(() => {\n    return this.currentPage\n      .getElements(containerName)\n      .first()\n      .element(self.currentPage.getElement(elementName).locator())\n      .getText()\n      .then(firstElementText => {\n        return self.currentPage.getElements(containerName).each(containerElement => {\n          containerElement\n            .element(self.currentPage.getElement(elementName).locator())\n            .getText()\n            .then(elementText => {\n              expect(elementText).toEqual(firstElementText);\n            });\n        });\n      });\n  });\n});\n\nThen(/^the element \"([^\"]*)\" should have an item with values:$/, function(elementName, data) {\n  const self = this;\n  const allElements = this.currentPage.getElements(elementName);\n  const hashedData = data.raw();\n\n  if (hashedData.length === 0) {\n    return Promise.reject('Missing table under the step.');\n  }\n\n  const promises = [];\n  return this.currentPage\n    .waitForVisibilityOf(elementName)\n    .then(() =>\n      allElements.each(element => {\n        hashedData.forEach(hash => {\n          promises.push(\n            matchers\n              .match(\n                element.element(self.currentPage.getElement(hash[0]).locator()),\n                variableStore.replaceTextVariables(hash[1])\n              )\n              .catch(() => false)\n          );\n        });\n      })\n    )\n    .then(() =>\n      Promise.all(promises).then(\n        handlePromises(hashedData, () => Promise.resolve(), () => Promise.reject('No matching element has been found.'))\n      )\n    );\n});\n\nThen(/^the element \"([^\"]*)\" should not have an item with values:$/, function(elementName, data) {\n  const self = this;\n  const allElements = this.currentPage.getElements(elementName);\n  const hashedData = data.raw();\n\n  if (hashedData.length === 0) {\n    return Promise.reject('Missing table under the step.');\n  }\n\n  const promises = [];\n\n  return allElements\n    .each(element => {\n      hashedData.forEach(hash => {\n        promises.push(\n          matchers\n            .match(\n              element.element(self.currentPage.getElement(hash[0]).locator()),\n              variableStore.replaceTextVariables(hash[1])\n            )\n            .catch(() => false)\n        );\n      });\n    })\n    .then(() =>\n      Promise.all(promises).then(\n        handlePromises(hashedData, () => Promise.reject('Matching element has been found'), () => Promise.resolve())\n      )\n    );\n});\n\nThen(/^\"([^\"]*)\" value on the \"([^\"]*)\" list is sorted in \"([^\"]*)\" order$/, function(\n  elementValue,\n  elementList,\n  dependency\n) {\n  const self = this;\n  const promise = [];\n\n  return this.currentPage.waitForVisibilityOf(elementList).then(() => {\n    return self.currentPage\n      .getElements(elementList)\n      .each(singleElement => {\n        promise.push(singleElement.element(self.currentPage.getElement(elementValue).locator()).getText());\n      })\n      .then(() => Promise.all(promise))\n      .then(elementsValues => comparators.compare(elementsValues, dependency));\n  });\n});\n\nWhen(/^I infinitely scroll to the \"([^\"]*)\" element$/, function(elementName) {\n  const self = this;\n\n  const scrollToLoader = () => {\n    return self.currentPage\n      .isPresent(elementName)\n      .then(isPresent => {\n        if (isPresent) {\n          return self.currentPage.scrollIntoElement(elementName);\n        }\n\n        return Promise.resolve();\n      })\n      .then(() => self.currentPage.isPresent(elementName))\n      .then(isPresent => {\n        if (isPresent) {\n          return browser.sleep(1000).then(() => scrollToLoader());\n        }\n\n        return Promise.resolve();\n      });\n  };\n\n  return scrollToLoader();\n});\n\nWhen(/^I press the \"([^\"]*)\" key$/, key => {\n  const keyTransformed = key.toUpperCase();\n\n  return Promise.resolve(\n    browser\n      .actions()\n      .sendKeys(protractor.Key[keyTransformed])\n      .perform()\n  );\n});\n\nWhen(/^I drag \"([^\"]*)\" element and drop over \"([^\"]*)\" element$/, async function(elementDrag, elementDrop) {\n  const wait = timeToWait => browser.sleep(timeToWait);\n\n  await this.currentPage.waitForVisibilityOf(elementDrag);\n  await browser\n    .actions()\n    .mouseMove(this.currentPage.getElement(elementDrag))\n    .perform();\n  await wait(200);\n  await browser\n    .actions()\n    .mouseDown()\n    .perform();\n  await wait(200);\n  await browser\n    .actions()\n    .mouseMove(this.currentPage.getElement(elementDrop))\n    .perform();\n  await wait(200);\n  await browser\n    .actions()\n    .mouseUp()\n    .perform();\n});\n"
  },
  {
    "path": "src/step_definitions/email.ts",
    "content": "import { Then } from 'cucumber';\nimport * as sugar from 'sugar-date/index';\nimport config from '../core/config.helper';\nimport { filters } from '../emails/filters';\nimport { regexBuilder } from '../matchers';\n\nimport { emailService } from '../emails';\n\nfunction stopInterval(interval, callback) {\n  clearInterval(interval);\n  callback();\n}\n\nfunction checkAttachmentsInEmail(email, filesExtensions, attachments) {\n  let fileAttachments = attachments.filter(attachment => attachment.attachment_type === 'attachment');\n\n  const missingFiles = filesExtensions.reduce((previous, current) => {\n    const expectedFile = fileAttachments.find(attachment => {\n      return (\n        regexBuilder.buildRegex(current.name).test(attachment.filename) &&\n        regexBuilder.buildRegex(current.type).test(attachment.content_type) &&\n        attachment.attachment_size >= current.minimalSize\n      );\n    });\n\n    if (typeof expectedFile === 'undefined') {\n      previous.push(current);\n      return previous;\n    }\n\n    fileAttachments = fileAttachments.filter(attachment => attachment.id !== expectedFile.id);\n\n    return previous;\n  }, []);\n\n  if (missingFiles.length === 0) {\n    return emailService.markAsRead(email);\n  }\n\n  return Promise.reject('Some attachments not found: ' + missingFiles.map(file => file.name).join(', '));\n}\n\nfunction filterEmails(emails, data) {\n  let originalEmails = emails;\n  const checks = data.raw().filter(elem => elem[0] !== 'file');\n\n  for (const check of checks) {\n    const checkType = check[0];\n    const checkValue = check[1];\n\n    originalEmails = filters.filter(originalEmails, checkType, checkValue, this);\n  }\n\n  return originalEmails;\n}\n\nfunction getFilesExtensions(data) {\n  return data\n    .raw()\n    .filter(elem => elem[0] === 'file')\n    .map(elem => {\n      return { name: elem[1], type: elem[2], minimalSize: elem[3] };\n    });\n}\n\nfunction rejectIfMaxRepeatsReached(filteredEmails, maxRepeats) {\n  if (filteredEmails.length === 0 && maxRepeats === 0) {\n    return Promise.reject('No emails found and maximum repeats reached');\n  }\n\n  return filteredEmails;\n}\n\nfunction rejectIfMoreThanOneEmailFound(filteredEmails) {\n  if (filteredEmails.length > 1) {\n    return Promise.reject('More than one email found');\n  }\n\n  return filteredEmails;\n}\n\nfunction rejectIfEmailFound(filteredEmails) {\n  if (filteredEmails.length > 0) {\n    return Promise.reject('Email has been found!');\n  }\n\n  return filteredEmails;\n}\n\nfunction validateEmailDate(filteredEmails) {\n  if (filteredEmails.length === 1 && sugar.Date.minutesFromNow(sugar.Date.create(filteredEmails[0].created_at)) < -10) {\n    return Promise.reject('Email was sent more than 10 minutes ago. This is probably not what you are looking for.');\n  }\n\n  return filteredEmails;\n}\n\nfunction validateEmailContentAndAttachments(filteredEmails, data, interval, sync) {\n  if (filteredEmails.length === 1) {\n    const filesExtensions = getFilesExtensions(data);\n\n    if (filesExtensions.length > 0) {\n      return emailService\n        .getAttachments(filteredEmails[0])\n        .then(checkAttachmentsInEmail.bind(null, filteredEmails[0], filesExtensions))\n        .then(stopInterval.bind(null, interval, sync));\n    }\n    return emailService.markAsRead(filteredEmails[0]).then(stopInterval.bind(null, interval, sync));\n  }\n}\n\nThen(/^the email has been sent and contains:$/, function(data, sync) {\n  const self = this;\n  const timeout = parseInt(config.intervalEmail) * 1000;\n  let maxRepeats = config.maxEmailRepeats === undefined ? 5 : parseInt(config.maxEmailRepeats);\n\n  const interval = setInterval(() => {\n    console.log('Checking mailbox for email...');\n\n    emailService\n      .getEmails()\n      .then(emails => filterEmails.call(self, emails, data))\n      .then(filteredEmails => rejectIfMaxRepeatsReached(filteredEmails, maxRepeats))\n      .then(filteredEmails => rejectIfMoreThanOneEmailFound(filteredEmails))\n      .then(filteredEmails => validateEmailDate(filteredEmails))\n      .then(filteredEmails => validateEmailContentAndAttachments(filteredEmails, data, interval, sync))\n      .then(() => maxRepeats--)\n      .catch(err => stopInterval(interval, sync.bind(null, err)));\n  }, timeout);\n});\n\nThen(/^the email with the following data has not been sent:$/, function(data, sync) {\n  const self = this;\n  const timeout = parseInt(config.intervalEmail) * 1000;\n  let maxRepeats = 5;\n\n  const interval = setInterval(() => {\n    console.log('Checking mailbox for email...');\n\n    emailService\n      .getEmails()\n      .then(emails => filterEmails.call(self, emails, data))\n      .then(filteredEmails => rejectIfEmailFound(filteredEmails))\n      .then(filteredEmails => rejectIfMaxRepeatsReached(filteredEmails, maxRepeats))\n      .then(() => maxRepeats--)\n      .catch(err => {\n        err === 'No emails found and maximum repeats reached'\n          ? stopInterval(interval, sync)\n          : stopInterval(interval, sync.bind(null, err));\n      });\n  }, timeout);\n});\n"
  },
  {
    "path": "src/step_definitions/file.ts",
    "content": "import { Then } from 'cucumber';\nimport fileManager from '../web/fs/file-manager.helper';\nimport variableStore from '../web/variable-store.helper';\n\nThen(/^the file \"([^\"]*)\" should be downloaded$/, filename => {\n  return fileManager.wasDownloaded(variableStore.replaceTextVariables(filename));\n});\n\nThen(/^the file \"([^\"]*)\" contains table data stored under \"([^\"]*)\" variable$/, (filename, variableName) => {\n  const file = fileManager.parseXLS(variableStore.replaceTextVariables(filename));\n  const storedData = variableStore.getVariableValue(variableName);\n  const rows = file.filter((row, index) => row.length > 0 && index > 0);\n\n  const findIndexes = () => {\n    const allFoundIndexesInRows = [];\n\n    storedData.forEach(storedItems => {\n      const foundIndexesInRow = [];\n      let previousFoundIndex = null;\n\n      storedItems.forEach(storedValue => {\n        for (const index in rows) {\n          if (rows.hasOwnProperty(index)) {\n            if (storedValue.match(/^\\d+$/)) {\n              if (previousFoundIndex !== null) {\n                foundIndexesInRow.push(rows[previousFoundIndex].indexOf(parseInt(storedValue)));\n                break;\n              }\n\n              if (rows[index].includes(parseInt(storedValue))) {\n                previousFoundIndex = index;\n                foundIndexesInRow.push(rows[index].indexOf(parseInt(storedValue)));\n                break;\n              }\n            }\n\n            if (previousFoundIndex !== null) {\n              foundIndexesInRow.push(rows[previousFoundIndex].indexOf(storedValue));\n              break;\n            }\n\n            if (rows[index].includes(storedValue)) {\n              previousFoundIndex = index;\n              foundIndexesInRow.push(rows[index].indexOf(storedValue));\n              break;\n            }\n          }\n        }\n      });\n\n      allFoundIndexesInRows.push(foundIndexesInRow);\n    });\n\n    return Promise.resolve(allFoundIndexesInRows);\n  };\n\n  return findIndexes().then(allFoundIndexes => {\n    if (allFoundIndexes[0].length !== storedData[0].length) {\n      return Promise.reject('Values not found!');\n    }\n\n    if (allFoundIndexes.length === 1) {\n      return Promise.resolve();\n    }\n\n    for (let index = 1; index < allFoundIndexes.length; index++) {\n      if (JSON.stringify(allFoundIndexes[index]) !== JSON.stringify(allFoundIndexes[index - 1])) {\n        return Promise.reject('Arrays are different!');\n      }\n    }\n  });\n});\n"
  },
  {
    "path": "src/step_definitions/form.ts",
    "content": "import { When, Then } from 'cucumber';\nimport { dictionaries } from '../dictionaries';\n\nWhen(/^I fill the \"([^\"]*)\" form with:$/, function(formName, data) {\n  const self = this;\n\n  return this.currentPage.waitForVisibilityOf(formName).then(() => self.currentPage.fillForm(data.raw()));\n});\n\nThen(/^the \"([^\"]*)\" form is filled with:$/, function(formName, data) {\n  const self = this;\n\n  return this.currentPage.waitForVisibilityOf(formName).then(() => self.currentPage.checkForm(data.raw()));\n});\n\nThen(/^the error messages should be displayed:$/, function(data) {\n  const self = this;\n  const table = data.rows();\n\n  const promise = [];\n\n  table.forEach(item => {\n    promise.push(\n      self.currentPage\n        .waitForVisibilityOf(item[0])\n        .then(() => self.currentPage[item[0]].getText())\n        .then(text => {\n          if (text.indexOf(dictionaries.findMappedValueByPhrase(item[1])) >= 0) {\n            return Promise.resolve();\n          }\n\n          return Promise.reject(\n            `Error \"${dictionaries.findMappedValueByPhrase(item[1])}\" for element \"${item[0]}\" was not found.`\n          );\n        })\n    );\n  });\n\n  return Promise.all(promise);\n});\n"
  },
  {
    "path": "src/step_definitions/generators.ts",
    "content": "import { When } from 'cucumber';\nimport { transformers } from '../transformers';\nimport variableStore from '../web/variable-store.helper';\n\nWhen(/^I generate random \"([^\"]*)\" as \"([^\"]*)\"$/, (generator, variableName) => {\n  return transformers.transform(`g:${generator}`).then(result => variableStore.storeVariable(variableName, result));\n});\n"
  },
  {
    "path": "src/step_definitions/navigation.ts",
    "content": "import { Then, Given } from 'cucumber';\n\nGiven(/^I visit the \"([^\"]*)\" page$/, function(pageName) {\n  expect(browser.page[pageName]).toBeDefined();\n\n  this.currentPage = browser.page[pageName];\n\n  return this.currentPage.visit();\n});\n\nGiven(/^I visit the \"([^\"]*)\" page with parameters:$/, function(pageName, data) {\n  expect(browser.page[pageName]).toBeDefined();\n\n  this.currentPage = browser.page[pageName];\n\n  return this.currentPage.visitWithParameters(data);\n});\n\nThen(/^the \"([^\"]*)\" page is displayed$/, function(pageName) {\n  const self = this;\n\n  return browser.page[pageName].isOn().then(checkResult => {\n    if (typeof checkResult !== 'object') {\n      return Promise.reject('Check result must be an object!!!');\n    }\n\n    self.currentPage = browser.page[pageName];\n    self.urlParameters = checkResult.parameters;\n  });\n});\n"
  },
  {
    "path": "src/step_definitions/performance.ts",
    "content": "import * as chalk from 'chalk';\nimport { When, Then } from 'cucumber';\nimport config from '../core/config.helper';\nimport { create as createAnalyser } from '../web/performance/time-to-first-byte-analyser.helper';\nimport * as fs from 'fs';\nimport { Proxy as Browsermob } from 'browsermob-proxy';\n\nconst analyser = createAnalyser();\nlet proxy;\n\nWhen(/^I start performance monitor mode$/, () => {\n  proxy = new Browsermob({\n    port: config.browserMob.serverPort,\n  });\n\n  let proxyReady = false;\n  proxy.start(config.browserMob.port, (err) => {\n    if (!err) {\n      proxy.startHAR(config.browserMob.port, 'test', true, true, () => {\n        proxyReady = true;\n      });\n    } else {\n      console.error(err);\n    }\n  });\n\n  browser.driver.wait(() => {\n    return proxyReady;\n  });\n});\n\nWhen(/^I save performance report file as \"([^\"]*)\"$/, function (fileName) {\n  const uniqueFileName = `${fileName}-${Date.now()}.har`;\n  let proxyDone = false;\n\n  proxy.getHAR(config.browserMob.port, (err, resp) => {\n    if (!err) {\n      console.log(`har saved at ${uniqueFileName}`);\n      fs.writeFileSync(`reports/performance/${uniqueFileName}`, resp, 'utf8');\n    } else {\n      console.err('Error getting HAR file: ' + err);\n    }\n    proxy.stop(config.browserMob.port, () => {\n      proxyDone = true;\n    });\n  });\n\n  return browser.driver.wait(() => {\n    this.performanceReportFile = uniqueFileName;\n    return proxyDone;\n  });\n});\n\nThen(/^the requests should take a maximum of \"([^\"]*)\" milliseconds$/, function (maxTiming) {\n  try {\n    const slowRequests = analyser.checkTiming(this.performanceReportFile, parseFloat(maxTiming));\n\n    if (slowRequests.length > 0) {\n      slowRequests.forEach(({ url, ttfb }) => {\n        console.log(\n          chalk.white.bgRed(\n            '\\r\\n',\n            'Slow request:',\n            '\\r\\n',\n            `URL: ${url}`,\n            '\\r\\n',\n            `TTFB: ${ttfb.toFixed(2)} ms`,\n            '\\r\\n'\n          )\n        );\n      });\n\n      return Promise.reject('TTFB value is too big! Details available above.');\n    }\n\n    return Promise.resolve();\n  } catch (err) {\n    return Promise.reject(err);\n  }\n});\n"
  },
  {
    "path": "src/step_definitions/tabs.ts",
    "content": "import { When } from 'cucumber';\n\nWhen(/^I switch to window number \"([^\"]*)\" of a browser$/, tabNumber => {\n  return browser.getAllWindowHandles().then(handles => browser.switchTo().window(handles[tabNumber - 1]));\n});\n\nWhen(/^I close the current browser tab$/, () => {\n  return browser\n    .close()\n    .then(() => browser.getAllWindowHandles())\n    .then(tabs => browser.switchTo().window(tabs[0]));\n});\n"
  },
  {
    "path": "src/tests/dictionaries/fake-dictionary.ts",
    "content": "import BaseDictionary from '../../dictionaries/base';\n\nclass FakeDictionary extends BaseDictionary {\n  constructor() {\n    super('fake-dictionary', {\n      'some-key': 'some-value',\n    });\n  }\n}\n\nexport = new FakeDictionary();\n"
  },
  {
    "path": "src/tests/init.ts",
    "content": "import * as protractor from 'protractor';\n\n// set global by to allow recursive call on src directory\nglobal.by = new protractor.ProtractorBy();\n\nrequire('../core/prototypes');\n"
  },
  {
    "path": "src/transformers/index.ts",
    "content": "import { create } from './transformers';\n\nexport const transformers = create();\n"
  },
  {
    "path": "src/transformers/transformer/dictionary.transformer.spec.ts",
    "content": "import { create as createDictionaries } from '../../dictionaries/dictionaries';\nimport { createDictionaryTransformer } from './dictionary.transformer';\nimport fakeDictionary = require('../../tests/dictionaries/fake-dictionary');\n\nconst dictionaries = createDictionaries();\n\ndictionaries.addDictionary(fakeDictionary);\n\ndescribe('Dictionary transformer', () => {\n  it('returns found position in the dictionary', () => {\n    const transformer = createDictionaryTransformer(dictionaries);\n\n    expect(transformer.transform('fake-dictionary:some-key')).toEqual('some-value');\n  });\n\n  it('returns true when the prefix is correct', () => {\n    const transformer = createDictionaryTransformer();\n\n    expect(transformer.isSatisfiedBy('d:')).toEqual(true);\n  });\n\n  it('returns false when the prefix is incorrect', () => {\n    const transformer = createDictionaryTransformer();\n\n    expect(transformer.isSatisfiedBy('v:')).toEqual(false);\n  });\n});\n"
  },
  {
    "path": "src/transformers/transformer/dictionary.transformer.ts",
    "content": "import { dictionaries as dicts, Dictionaries } from '../../dictionaries';\nimport { Transformer } from '../transformer.interface';\n\nclass DictionaryTransformer implements Transformer {\n  constructor(private dictionaries: Dictionaries) {}\n\n  public isSatisfiedBy(prefix) {\n    return prefix === 'd:';\n  }\n\n  public transform(value) {\n    const splittedValue = value.split(':');\n    return this.dictionaries.getMappedValue(splittedValue[0], splittedValue[1]);\n  }\n}\nexport const createDictionaryTransformer = (dictionaries = dicts) => new DictionaryTransformer(dictionaries);\n"
  },
  {
    "path": "src/transformers/transformer/generator.transformer.spec.ts",
    "content": "import { createGeneratorTransformer } from './generator.transformer';\n\ndescribe('Generator transformer', () => {\n  it('returns true when the prefix is correct', () => {\n    const transformer = createGeneratorTransformer();\n\n    expect(transformer.isSatisfiedBy('g:')).toEqual(true);\n  });\n\n  it('returns false when the prefix is incorrect', () => {\n    const transformer = createGeneratorTransformer();\n\n    expect(transformer.isSatisfiedBy('d:')).toEqual(false);\n  });\n\n  it('returns generated value ', () => {\n    const mockedGenerators: any = {\n      generate: value => 'my-generated-value',\n    };\n    const transformer = createGeneratorTransformer(mockedGenerators);\n\n    expect(transformer.transform('generator:generate')).toEqual('my-generated-value');\n  });\n});\n"
  },
  {
    "path": "src/transformers/transformer/generator.transformer.ts",
    "content": "import { generators, Generators } from '../../generators';\nimport { Transformer } from '../transformer.interface';\n\nclass GeneratorTransformer implements Transformer {\n  constructor(public generator: Generators) {}\n\n  public isSatisfiedBy(prefix) {\n    return prefix === 'g:';\n  }\n\n  public transform(value) {\n    const splittedValues = value.split(':');\n    const generatorName = splittedValues[0];\n\n    return this.generator.generate(generatorName, splittedValues.slice(1));\n  }\n}\nexport const createGeneratorTransformer = (geners = generators) => new GeneratorTransformer(geners);\n"
  },
  {
    "path": "src/transformers/transformer/variable-store.transformer.spec.ts",
    "content": "import { createVariableStoreTransformer } from './variable-store.transformer';\n\ndescribe('Variable store transformer', () => {\n  it('returns replaced text', () => {\n    const fakeValue: any = {\n      getVariableValue: () => 'expected value',\n    };\n    const transformer = createVariableStoreTransformer(fakeValue);\n\n    expect(transformer.transform('given value')).toEqual('expected value');\n  });\n\n  it('returns true when the prefix is correct', () => {\n    const transformer = createVariableStoreTransformer();\n\n    expect(transformer.isSatisfiedBy('v:')).toEqual(true);\n  });\n\n  it('returns false when the prefix is incorrect', () => {\n    const transformer = createVariableStoreTransformer();\n\n    expect(transformer.isSatisfiedBy('t:')).toEqual(false);\n  });\n});\n"
  },
  {
    "path": "src/transformers/transformer/variable-store.transformer.ts",
    "content": "import store from '../../web/variable-store.helper';\nimport { VariableStore } from '../../web/variable-store.helper';\nimport { Transformer } from '../transformer.interface';\n\nclass VariableStoreTransformer implements Transformer {\n  constructor(private variableStore: VariableStore) {}\n\n  public isSatisfiedBy(prefix) {\n    return prefix === 'v:';\n  }\n\n  public transform(value) {\n    return this.variableStore.getVariableValue(value);\n  }\n}\nexport const createVariableStoreTransformer = (variableStore = store) => new VariableStoreTransformer(variableStore);\n"
  },
  {
    "path": "src/transformers/transformer.interface.ts",
    "content": "export interface Transformer {\n  isSatisfiedBy(prefix: string): boolean;\n  transform(transform: string): any;\n}\n"
  },
  {
    "path": "src/transformers/transformers.spec.ts",
    "content": "import { create } from './transformers';\n\nconst transformers = create();\n\ndescribe('Value transformers', () => {\n  it('returns the same value if transformer has not been found', () => {\n    const emptyTransformer = create([]);\n\n    expect(emptyTransformer.transform('some value')).toEqual('some value');\n  });\n\n  it('returns transformed value when expected transformer has been found', () => {\n    const fakeTransformer: any = {\n      isSatisfiedBy: prefix => prefix === 'v:',\n      transform: value => {\n        expect(value).toEqual('value');\n        return 'expected value';\n      },\n    };\n    const transformers = create([fakeTransformer]);\n\n    expect(transformers.transform('v:value')).toEqual('expected value');\n  });\n\n  it('adds a transformer', () => {\n    const customTransformer = {\n      isSatisfiedBy: prefix => prefix === 'j:',\n      transform: () => 'custom-transformer',\n    };\n\n    transformers.addTransformer(customTransformer);\n\n    expect(transformers.transform('j:custom-transformer')).toEqual('custom-transformer');\n  });\n});\n"
  },
  {
    "path": "src/transformers/transformers.ts",
    "content": "import { createDictionaryTransformer } from './transformer/dictionary.transformer';\nimport { createGeneratorTransformer } from './transformer/generator.transformer';\nimport { createVariableStoreTransformer } from './transformer/variable-store.transformer';\nimport { Transformer } from './transformer.interface';\n\nclass Transformers {\n  constructor(private availableTransformers: Transformer[]) {}\n\n  public transform(value: string): any {\n    const transformer = this.findTransformer(value.substr(0, 2));\n\n    if (transformer === undefined) {\n      return value;\n    }\n\n    return transformer.transform(value.substr(2));\n  }\n\n  public findTransformer(prefix: string): Transformer {\n    return this.availableTransformers.find(transformer => transformer.isSatisfiedBy(prefix));\n  }\n\n  public addTransformer(transformer: Transformer): void {\n    this.availableTransformers.push(transformer);\n  }\n}\n\nconst transformers = [createVariableStoreTransformer(), createDictionaryTransformer(), createGeneratorTransformer()];\n\nexport const create = (transf = transformers) => new Transformers(transf);\n"
  },
  {
    "path": "src/web/browsers/browsers-config.helper.ts",
    "content": "import * as glob from 'glob';\nimport * as path from 'path';\nimport { createFirefoxProfile } from './create-firefox-profile.helper';\nimport { safariBrowserConfigurator } from './safari-browser-configurator.helper';\nimport { prepareBrowserInstance } from '../parallel/prepare-browser-instance-specs.helper';\nimport { chunkSpecs } from '../parallel/chunk-specs.helper';\n\nconst getDefaultBrowsersConfigs = (config): any => {\n  const chromeConfig = {\n    browserName: 'chrome',\n    chromeOptions: {\n      args: [],\n      prefs: {\n        credentials_enable_service: false,\n        profile: {\n          password_manager_enabled: false,\n        },\n        download: {\n          prompt_for_download: false,\n          default_directory: config.projectPath + config.downloads,\n          directory_upgrade: true,\n        },\n      },\n    },\n  };\n\n  const firefoxConfig = {\n    browserName: 'firefox',\n    marionette: true,\n    'moz:firefoxOptions': {\n      args: [],\n    },\n  };\n\n  const safariConfig = {\n    browserName: 'safari',\n  };\n\n  const ieConfig = {\n    browserName: 'internet explorer',\n  };\n\n  return {\n    chromeConfig,\n    firefoxConfig,\n    safariConfig,\n    ieConfig,\n  };\n};\n\nconst getExtendedBrowsersConfigs = (config, commandArgs): any => {\n  const configs = getDefaultBrowsersConfigs(config);\n\n  if (config.performance) {\n    configs.chromeConfig.proxy = {\n      proxyType: 'manual',\n      httpProxy: `${config.browserMob.host}:${config.browserMob.port}`,\n      sslProxy: `${config.browserMob.host}:${config.browserMob.port}`,\n    };\n  }\n\n  if (config.noGpu) {\n    configs.chromeConfig.chromeOptions.args = [\n      ...configs.chromeConfig.chromeOptions.args,\n      '--disable-gpu',\n      '--disable-impl-side-painting',\n      '--disable-gpu-sandbox',\n      '--disable-accelerated-2d-canvas',\n      '--disable-accelerated-jpeg-decoding',\n      '--no-sandbox',\n    ];\n  }\n\n  if (\n    (config.headless && commandArgs.headless === undefined) ||\n    (commandArgs.headless && commandArgs.headless !== 'false')\n  ) {\n    configs.chromeConfig.chromeOptions.args = [\n      ...configs.chromeConfig.chromeOptions.args,\n      '--headless',\n      `--window-size=${config.browserWidth}x${config.browserHeight}`,\n    ];\n\n    configs.firefoxConfig['moz:firefoxOptions'].args = [\n      ...configs.firefoxConfig['moz:firefoxOptions'].args,\n      '-headless',\n      `--window-size=${config.browserWidth}x${config.browserHeight}`,\n    ];\n  }\n\n  return configs;\n};\n\nexport const browsersConfiguration = (config, commandArgs): any => {\n  return () => {\n    const browsersSettings = [];\n    const browserConfigs = getExtendedBrowsersConfigs(config, commandArgs);\n    const allSpecs = glob.sync(config.features.map(file => path.join(config.projectPath, file, '**/*.feature'))[0]);\n    const isParallel =\n      commandArgs.parallel !== undefined && Number.isInteger(commandArgs.parallel) && commandArgs.parallel !== 0;\n    const numberOfInstances = isParallel\n      ? commandArgs.parallel >= allSpecs.length\n        ? allSpecs.length\n        : commandArgs.parallel\n      : 1;\n    const expectedArrayLength = Math.ceil(allSpecs.length / numberOfInstances);\n    const chunkedSpecs = chunkSpecs(commandArgs, allSpecs, expectedArrayLength, numberOfInstances);\n\n    if (allSpecs.length === 0) {\n      throw new Error('Could not find any files matching regex in the directory!');\n    }\n\n    const pushPreparedBrowserInstance = browserType => {\n      for (let i = 0; i < numberOfInstances; i++) {\n        browsersSettings.push(prepareBrowserInstance(browserConfigs[browserType], chunkedSpecs[i]));\n      }\n    };\n\n    if (commandArgs.browserstack) {\n      return Promise.resolve([prepareBrowserInstance(config.browserstack.capabilities, allSpecs)]);\n    }\n\n    if (commandArgs.firefox) {\n      browserConfigs.firefoxConfig.firefox_profile = createFirefoxProfile(config);\n      pushPreparedBrowserInstance('firefoxConfig');\n    }\n\n    if (commandArgs.safari) {\n      safariBrowserConfigurator(config);\n      pushPreparedBrowserInstance('safariConfig');\n    }\n\n    if (commandArgs.ie) {\n      pushPreparedBrowserInstance('ieConfig');\n    }\n\n    if (\n      commandArgs.chrome ||\n      (commandArgs.firefox === undefined && commandArgs.safari === undefined && commandArgs.ie === undefined)\n    ) {\n      pushPreparedBrowserInstance('chromeConfig');\n    }\n\n    return Promise.resolve(browsersSettings);\n  };\n};\n\nexport const setSeleniumAddress = (commandArgs, config): string => {\n  return commandArgs.browserstack ? config.browserstack.seleniumAddress : '';\n};\n"
  },
  {
    "path": "src/web/browsers/browserstack-config.helper.ts",
    "content": "import * as browserstack from 'browserstack-local';\nimport * as chalk from 'chalk';\nimport * as shell from 'shelljs';\nimport config from '../../core/config.helper';\n\nexport const disconnectBrowserstack = (browserstackEnabled: boolean) => {\n  if (browserstackEnabled && config.browserstack) {\n    const browserstackPid = shell.exec(`lsof -t -i :${config.browserstack.defaultPort}`).stdout;\n\n    if (browserstackPid.length > 0) {\n      return shell.exec(`kill -9 ${browserstackPid}`);\n    }\n  }\n\n  return Promise.resolve();\n};\n\nexport const connectBrowserstack = (browserstackKey: string) => {\n  console.log(\n    chalk.black.bgYellow(\n      'Keep in mind that Browserstack capabilities cannot be used with the local. Check the documentation for more information!'\n    )\n  );\n\n  disconnectBrowserstack(true);\n\n  return new Promise((resolve, reject) => {\n    const bsLocal = new browserstack.Local();\n    bsLocal.start({ key: browserstackKey }, (error) => {\n      if (error) {\n        return reject(error);\n      }\n      console.log('Connected to the Browsertack Selenium server! Now testing...');\n      resolve(true);\n    });\n  });\n};\n"
  },
  {
    "path": "src/web/browsers/create-firefox-profile.helper.ts",
    "content": "import * as firefox from 'selenium-webdriver/firefox';\nimport * as path from 'path';\n\nexport const createFirefoxProfile = config => {\n  const profile = new firefox.Profile();\n\n  profile.setPreference('browser.download.dir', path.join(config.projectPath, config.downloads));\n  profile.setPreference('browser.download.folderList', 2);\n  profile.setPreference('browser.download.panel.shown', true);\n  profile.setPreference('browser.safebrowsing.downloads.enabled', false);\n  profile.setPreference('browser.helperApps.alwaysAsk.force', false);\n  profile.setPreference('browser.download.manager.showWhenStarting', false);\n  profile.setPreference('browser.download.manager.showAlertOnComplete', false);\n  profile.setPreference(\n    'browser.helperApps.neverAsk.saveToDisk',\n    'application/vnd.hzn-3d-crossword;video/3gpp;video/3gpp2;application/vnd.mseq;application/vnd.3m.post-it-notes;application/vnd.3gpp.pic-bw-large;application/vnd.3gpp.pic-bw-small;application/vnd.3gpp.pic-bw-var;application/vnd.3gp2.tcap;application/x-7z-compressed;application/x-abiword;application/x-ace-compressed;application/vnd.americandynamics.acc;application/vnd.acucobol;application/vnd.acucorp;audio/adpcm;application/x-authorware-bin;application/x-athorware-map;application/x-authorware-seg;application/vnd.adobe.air-application-installer-package+zip;application/x-shockwave-flash;application/vnd.adobe.fxp;application/pdf;application/vnd.cups-ppd;application/x-director;applicaion/vnd.adobe.xdp+xml;application/vnd.adobe.xfdf;audio/x-aac;application/vnd.ahead.space;application/vnd.airzip.filesecure.azf;application/vnd.airzip.filesecure.azs;application/vnd.amazon.ebook;application/vnd.amiga.ami;applicatin/andrew-inset;application/vnd.android.package-archive;application/vnd.anser-web-certificate-issue-initiation;application/vnd.anser-web-funds-transfer-initiation;application/vnd.antix.game-component;application/vnd.apple.installe+xml;application/applixware;application/vnd.hhe.lesson-player;application/vnd.aristanetworks.swi;text/x-asm;application/atomcat+xml;application/atomsvc+xml;application/atom+xml;application/pkix-attr-cert;audio/x-aiff;video/x-msvieo;application/vnd.audiograph;image/vnd.dxf;model/vnd.dwf;text/plain-bas;application/x-bcpio;application/octet-stream;image/bmp;application/x-bittorrent;application/vnd.rim.cod;application/vnd.blueice.multipass;application/vnd.bm;application/x-sh;image/prs.btif;application/vnd.businessobjects;application/x-bzip;application/x-bzip2;application/x-csh;text/x-c;application/vnd.chemdraw+xml;text/css;chemical/x-cdx;chemical/x-cml;chemical/x-csml;application/vn.contact.cmsg;application/vnd.claymore;application/vnd.clonk.c4group;image/vnd.dvb.subtitle;application/cdmi-capability;application/cdmi-container;application/cdmi-domain;application/cdmi-object;application/cdmi-queue;applicationvnd.cluetrust.cartomobile-config;application/vnd.cluetrust.cartomobile-config-pkg;image/x-cmu-raster;model/vnd.collada+xml;text/csv;application/mac-compactpro;application/vnd.wap.wmlc;image/cgm;x-conference/x-cooltalk;image/x-cmx;application/vnd.xara;application/vnd.cosmocaller;application/x-cpio;application/vnd.crick.clicker;application/vnd.crick.clicker.keyboard;application/vnd.crick.clicker.palette;application/vnd.crick.clicker.template;application/vn.crick.clicker.wordbank;application/vnd.criticaltools.wbs+xml;application/vnd.rig.cryptonote;chemical/x-cif;chemical/x-cmdf;application/cu-seeme;application/prs.cww;text/vnd.curl;text/vnd.curl.dcurl;text/vnd.curl.mcurl;text/vnd.crl.scurl;application/vnd.curl.car;application/vnd.curl.pcurl;application/vnd.yellowriver-custom-menu;application/dssc+der;application/dssc+xml;application/x-debian-package;audio/vnd.dece.audio;image/vnd.dece.graphic;video/vnd.dec.hd;video/vnd.dece.mobile;video/vnd.uvvu.mp4;video/vnd.dece.pd;video/vnd.dece.sd;video/vnd.dece.video;application/x-dvi;application/vnd.fdsn.seed;application/x-dtbook+xml;application/x-dtbresource+xml;application/vnd.dvb.ait;applcation/vnd.dvb.service;audio/vnd.digital-winds;image/vnd.djvu;application/xml-dtd;application/vnd.dolby.mlp;application/x-doom;application/vnd.dpgraph;audio/vnd.dra;application/vnd.dreamfactory;audio/vnd.dts;audio/vnd.dts.hd;imag/vnd.dwg;application/vnd.dynageo;application/ecmascript;application/vnd.ecowin.chart;image/vnd.fujixerox.edmics-mmr;image/vnd.fujixerox.edmics-rlc;application/exi;application/vnd.proteus.magazine;application/epub+zip;message/rfc82;application/vnd.enliven;application/vnd.is-xpr;image/vnd.xiff;application/vnd.xfdl;application/emma+xml;application/vnd.ezpix-album;application/vnd.ezpix-package;image/vnd.fst;video/vnd.fvt;image/vnd.fastbidsheet;application/vn.denovo.fcselayout-link;video/x-f4v;video/x-flv;image/vnd.fpx;image/vnd.net-fpx;text/vnd.fmi.flexstor;video/x-fli;application/vnd.fluxtime.clip;application/vnd.fdf;text/x-fortran;application/vnd.mif;application/vnd.framemaker;imae/x-freehand;application/vnd.fsc.weblaunch;application/vnd.frogans.fnc;application/vnd.frogans.ltf;application/vnd.fujixerox.ddd;application/vnd.fujixerox.docuworks;application/vnd.fujixerox.docuworks.binder;application/vnd.fujitu.oasys;application/vnd.fujitsu.oasys2;application/vnd.fujitsu.oasys3;application/vnd.fujitsu.oasysgp;application/vnd.fujitsu.oasysprs;application/x-futuresplash;application/vnd.fuzzysheet;image/g3fax;application/vnd.gmx;model/vn.gtw;application/vnd.genomatix.tuxedo;application/vnd.geogebra.file;application/vnd.geogebra.tool;model/vnd.gdl;application/vnd.geometry-explorer;application/vnd.geonext;application/vnd.geoplan;application/vnd.geospace;applicatio/x-font-ghostscript;application/x-font-bdf;application/x-gtar;application/x-texinfo;application/x-gnumeric;application/vnd.google-earth.kml+xml;application/vnd.google-earth.kmz;application/vnd.grafeq;image/gif;text/vnd.graphviz;aplication/vnd.groove-account;application/vnd.groove-help;application/vnd.groove-identity-message;application/vnd.groove-injector;application/vnd.groove-tool-message;application/vnd.groove-tool-template;application/vnd.groove-vcar;video/h261;video/h263;video/h264;application/vnd.hp-hpid;application/vnd.hp-hps;application/x-hdf;audio/vnd.rip;application/vnd.hbci;application/vnd.hp-jlyt;application/vnd.hp-pcl;application/vnd.hp-hpgl;application/vnd.yamaha.h-script;application/vnd.yamaha.hv-dic;application/vnd.yamaha.hv-voice;application/vnd.hydrostatix.sof-data;application/hyperstudio;application/vnd.hal+xml;text/html;application/vnd.ibm.rights-management;application/vnd.ibm.securecontainer;text/calendar;application/vnd.iccprofile;image/x-icon;application/vnd.igloader;image/ief;application/vnd.immervision-ivp;application/vnd.immervision-ivu;application/reginfo+xml;text/vnd.in3d.3dml;text/vnd.in3d.spot;mode/iges;application/vnd.intergeo;application/vnd.cinderella;application/vnd.intercon.formnet;application/vnd.isac.fcs;application/ipfix;application/pkix-cert;application/pkixcmp;application/pkix-crl;application/pkix-pkipath;applicaion/vnd.insors.igm;application/vnd.ipunplugged.rcprofile;application/vnd.irepository.package+xml;text/vnd.sun.j2me.app-descriptor;application/java-archive;application/java-vm;application/x-java-jnlp-file;application/java-serializd-object;text/x-java-source,java;application/javascript;application/json;application/vnd.joost.joda-archive;video/jpm;image/jpeg;video/jpeg;application/vnd.kahootz;application/vnd.chipnuts.karaoke-mmd;application/vnd.kde.karbon;aplication/vnd.kde.kchart;application/vnd.kde.kformula;application/vnd.kde.kivio;application/vnd.kde.kontour;application/vnd.kde.kpresenter;application/vnd.kde.kspread;application/vnd.kde.kword;application/vnd.kenameaapp;applicatin/vnd.kidspiration;application/vnd.kinar;application/vnd.kodak-descriptor;application/vnd.las.las+xml;application/x-latex;application/vnd.llamagraphics.life-balance.desktop;application/vnd.llamagraphics.life-balance.exchange+xml;application/vnd.jam;application/vnd.lotus-1-2-3;application/vnd.lotus-approach;application/vnd.lotus-freelance;application/vnd.lotus-notes;application/vnd.lotus-organizer;application/vnd.lotus-screencam;application/vnd.lotus-wordro;audio/vnd.lucent.voice;audio/x-mpegurl;video/x-m4v;application/mac-binhex40;application/vnd.macports.portpkg;application/vnd.osgeo.mapguide.package;application/marc;application/marcxml+xml;application/mxf;application/vnd.wolfrm.player;application/mathematica;application/mathml+xml;application/mbox;application/vnd.medcalcdata;application/mediaservercontrol+xml;application/vnd.mediastation.cdkey;application/vnd.mfer;application/vnd.mfmp;model/mesh;appliation/mads+xml;application/mets+xml;application/mods+xml;application/metalink4+xml;application/vnd.ms-powerpoint.template.macroenabled.12;application/vnd.ms-word.document.macroenabled.12;application/vnd.ms-word.template.macroenabed.12;application/vnd.mcd;application/vnd.micrografx.flo;application/vnd.micrografx.igx;application/vnd.eszigno3+xml;application/x-msaccess;video/x-ms-asf;application/x-msdownload;application/vnd.ms-artgalry;application/vnd.ms-ca-compressed;application/vnd.ms-ims;application/x-ms-application;application/x-msclip;image/vnd.ms-modi;application/vnd.ms-fontobject;application/vnd.ms-excel;application/vnd.ms-excel.addin.macroenabled.12;application/vnd.ms-excelsheet.binary.macroenabled.12;application/vnd.ms-excel.template.macroenabled.12;application/vnd.ms-excel.sheet.macroenabled.12;application/vnd.ms-htmlhelp;application/x-mscardfile;application/vnd.ms-lrm;application/x-msmediaview;aplication/x-msmoney;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/vnd.openxmlformats-officedocument.presentationml.slide;application/vnd.openxmlformats-officedocument.presentationml.slideshw;application/vnd.openxmlformats-officedocument.presentationml.template;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.openxmlformats-officedocument.spreadsheetml.template;application/vnd.openxmformats-officedocument.wordprocessingml.document;application/vnd.openxmlformats-officedocument.wordprocessingml.template;application/x-msbinder;application/vnd.ms-officetheme;application/onenote;audio/vnd.ms-playready.media.pya;vdeo/vnd.ms-playready.media.pyv;application/vnd.ms-powerpoint;application/vnd.ms-powerpoint.addin.macroenabled.12;application/vnd.ms-powerpoint.slide.macroenabled.12;application/vnd.ms-powerpoint.presentation.macroenabled.12;appliation/vnd.ms-powerpoint.slideshow.macroenabled.12;application/vnd.ms-project;application/x-mspublisher;application/x-msschedule;application/x-silverlight-app;application/vnd.ms-pki.stl;application/vnd.ms-pki.seccat;application/vn.visio;video/x-ms-wm;audio/x-ms-wma;audio/x-ms-wax;video/x-ms-wmx;application/x-ms-wmd;application/vnd.ms-wpl;application/x-ms-wmz;video/x-ms-wmv;video/x-ms-wvx;application/x-msmetafile;application/x-msterminal;application/msword;application/x-mswrite;application/vnd.ms-works;application/x-ms-xbap;application/vnd.ms-xpsdocument;audio/midi;application/vnd.ibm.minipay;application/vnd.ibm.modcap;application/vnd.jcp.javame.midlet-rms;application/vnd.tmobile-ivetv;application/x-mobipocket-ebook;application/vnd.mobius.mbk;application/vnd.mobius.dis;application/vnd.mobius.plc;application/vnd.mobius.mqy;application/vnd.mobius.msl;application/vnd.mobius.txf;application/vnd.mobius.daf;tex/vnd.fly;application/vnd.mophun.certificate;application/vnd.mophun.application;video/mj2;audio/mpeg;video/vnd.mpegurl;video/mpeg;application/mp21;audio/mp4;video/mp4;application/mp4;application/vnd.apple.mpegurl;application/vnd.msician;application/vnd.muvee.style;application/xv+xml;application/vnd.nokia.n-gage.data;application/vnd.nokia.n-gage.symbian.install;application/x-dtbncx+xml;application/x-netcdf;application/vnd.neurolanguage.nlu;application/vnd.na;application/vnd.noblenet-directory;application/vnd.noblenet-sealer;application/vnd.noblenet-web;application/vnd.nokia.radio-preset;application/vnd.nokia.radio-presets;text/n3;application/vnd.novadigm.edm;application/vnd.novadim.edx;application/vnd.novadigm.ext;application/vnd.flographit;audio/vnd.nuera.ecelp4800;audio/vnd.nuera.ecelp7470;audio/vnd.nuera.ecelp9600;application/oda;application/ogg;audio/ogg;video/ogg;application/vnd.oma.dd2+xml;applicatin/vnd.oasis.opendocument.text-web;application/oebps-package+xml;application/vnd.intu.qbo;application/vnd.openofficeorg.extension;application/vnd.yamaha.openscoreformat;audio/webm;video/webm;application/vnd.oasis.opendocument.char;application/vnd.oasis.opendocument.chart-template;application/vnd.oasis.opendocument.database;application/vnd.oasis.opendocument.formula;application/vnd.oasis.opendocument.formula-template;application/vnd.oasis.opendocument.grapics;application/vnd.oasis.opendocument.graphics-template;application/vnd.oasis.opendocument.image;application/vnd.oasis.opendocument.image-template;application/vnd.oasis.opendocument.presentation;application/vnd.oasis.opendocumen.presentation-template;application/vnd.oasis.opendocument.spreadsheet;application/vnd.oasis.opendocument.spreadsheet-template;application/vnd.oasis.opendocument.text;application/vnd.oasis.opendocument.text-master;application/vnd.asis.opendocument.text-template;image/ktx;application/vnd.sun.xml.calc;application/vnd.sun.xml.calc.template;application/vnd.sun.xml.draw;application/vnd.sun.xml.draw.template;application/vnd.sun.xml.impress;application/vnd.sun.xl.impress.template;application/vnd.sun.xml.math;application/vnd.sun.xml.writer;application/vnd.sun.xml.writer.global;application/vnd.sun.xml.writer.template;application/x-font-otf;application/vnd.yamaha.openscoreformat.osfpvg+xml;application/vnd.osgi.dp;application/vnd.palm;text/x-pascal;application/vnd.pawaafile;application/vnd.hp-pclxl;application/vnd.picsel;image/x-pcx;image/vnd.adobe.photoshop;application/pics-rules;image/x-pict;application/x-chat;aplication/pkcs10;application/x-pkcs12;application/pkcs7-mime;application/pkcs7-signature;application/x-pkcs7-certreqresp;application/x-pkcs7-certificates;application/pkcs8;application/vnd.pocketlearn;image/x-portable-anymap;image/-portable-bitmap;application/x-font-pcf;application/font-tdpfr;application/x-chess-pgn;image/x-portable-graymap;image/png;image/x-portable-pixmap;application/pskc+xml;application/vnd.ctc-posml;application/postscript;application/xfont-type1;application/vnd.powerbuilder6;application/pgp-encrypted;application/pgp-signature;application/vnd.previewsystems.box;application/vnd.pvi.ptid1;application/pls+xml;application/vnd.pg.format;application/vnd.pg.osasli;tex/prs.lines.tag;application/x-font-linux-psf;application/vnd.publishare-delta-tree;application/vnd.pmi.widget;application/vnd.quark.quarkxpress;application/vnd.epson.esf;application/vnd.epson.msf;application/vnd.epson.ssf;applicaton/vnd.epson.quickanime;application/vnd.intu.qfx;video/quicktime;application/x-rar-compressed;audio/x-pn-realaudio;audio/x-pn-realaudio-plugin;application/rsd+xml;application/vnd.rn-realmedia;application/vnd.realvnc.bed;applicatin/vnd.recordare.musicxml;application/vnd.recordare.musicxml+xml;application/relax-ng-compact-syntax;application/vnd.data-vision.rdz;application/rdf+xml;application/vnd.cloanto.rp9;application/vnd.jisp;application/rtf;text/richtex;application/vnd.route66.link66+xml;application/rss+xml;application/shf+xml;application/vnd.sailingtracker.track;image/svg+xml;application/vnd.sus-calendar;application/sru+xml;application/set-payment-initiation;application/set-reistration-initiation;application/vnd.sema;application/vnd.semd;application/vnd.semf;application/vnd.seemail;application/x-font-snf;application/scvp-vp-request;application/scvp-vp-response;application/scvp-cv-request;application/svp-cv-response;application/sdp;text/x-setext;video/x-sgi-movie;application/vnd.shana.informed.formdata;application/vnd.shana.informed.formtemplate;application/vnd.shana.informed.interchange;application/vnd.shana.informed.package;application/thraud+xml;application/x-shar;image/x-rgb;application/vnd.epson.salt;application/vnd.accpac.simply.aso;application/vnd.accpac.simply.imp;application/vnd.simtech-mindmapper;application/vnd.commonspace;application/vnd.ymaha.smaf-audio;application/vnd.smaf;application/vnd.yamaha.smaf-phrase;application/vnd.smart.teacher;application/vnd.svd;application/sparql-query;application/sparql-results+xml;application/srgs;application/srgs+xml;application/sml+xml;application/vnd.koan;text/sgml;application/vnd.stardivision.calc;application/vnd.stardivision.draw;application/vnd.stardivision.impress;application/vnd.stardivision.math;application/vnd.stardivision.writer;application/vnd.tardivision.writer-global;application/vnd.stepmania.stepchart;application/x-stuffit;application/x-stuffitx;application/vnd.solent.sdkm+xml;application/vnd.olpc-sugar;audio/basic;application/vnd.wqd;application/vnd.symbian.install;application/smil+xml;application/vnd.syncml+xml;application/vnd.syncml.dm+wbxml;application/vnd.syncml.dm+xml;application/x-sv4cpio;application/x-sv4crc;application/sbml+xml;text/tab-separated-values;image/tiff;application/vnd.to.intent-module-archive;application/x-tar;application/x-tcl;application/x-tex;application/x-tex-tfm;application/tei+xml;text/plain;application/vnd.spotfire.dxp;application/vnd.spotfire.sfs;application/timestamped-data;applicationvnd.trid.tpt;application/vnd.triscape.mxs;text/troff;application/vnd.trueapp;application/x-font-ttf;text/turtle;application/vnd.umajin;application/vnd.uoml+xml;application/vnd.unity;application/vnd.ufdl;text/uri-list;application/nd.uiq.theme;application/x-ustar;text/x-uuencode;text/x-vcalendar;text/x-vcard;application/x-cdlink;application/vnd.vsf;model/vrml;application/vnd.vcx;model/vnd.mts;model/vnd.vtu;application/vnd.visionary;video/vnd.vivo;applicatin/ccxml+xml,;application/voicexml+xml;application/x-wais-source;application/vnd.wap.wbxml;image/vnd.wap.wbmp;audio/x-wav;application/davmount+xml;application/x-font-woff;application/wspolicy+xml;image/webp;application/vnd.webturb;application/widget;application/winhlp;text/vnd.wap.wml;text/vnd.wap.wmlscript;application/vnd.wap.wmlscriptc;application/vnd.wordperfect;application/vnd.wt.stf;application/wsdl+xml;image/x-xbitmap;image/x-xpixmap;image/x-xwindowump;application/x-x509-ca-cert;application/x-xfig;application/xhtml+xml;application/xml;application/xcap-diff+xml;application/xenc+xml;application/patch-ops-error+xml;application/resource-lists+xml;application/rls-services+xml;aplication/resource-lists-diff+xml;application/xslt+xml;application/xop+xml;application/x-xpinstall;application/xspf+xml;application/vnd.mozilla.xul+xml;chemical/x-xyz;text/yaml;application/yang;application/yin+xml;application/vnd.ul;application/zip;application/vnd.handheld-entertainment+xml;application/vnd.zzazz.deck+xml'\n  );\n  profile.setPreference('pdfjs.disabled', true);\n\n  return profile;\n};\n"
  },
  {
    "path": "src/web/browsers/get-browser-drivers.helper.ts",
    "content": "import * as fs from 'fs';\n\nexport const getBrowsersDrivers = (commandArgs): string[] => {\n  const drivers: string[] = [];\n  const pathToDrivers = './node_modules/protractor/node_modules/webdriver-manager/selenium';\n\n  if (commandArgs.ie) {\n    // This is required as Protractor cannot find IEDriverServer. The other drivers does not require any additional configuration.\n    const availableDrivers = fs.readdirSync(pathToDrivers);\n    const IEDriver = availableDrivers.filter(item => item.match('IEDriverServer([0-9].[0-9]{3}.[0-9]).exe'))[0];\n\n    drivers.push(`-Dwebdriver.ie.driver=${pathToDrivers}/${IEDriver}`);\n  }\n\n  return drivers;\n};\n"
  },
  {
    "path": "src/web/browsers/safari-browser-configurator.helper.ts",
    "content": "import * as path from 'path';\nimport * as shell from 'shelljs';\n\nexport const safariBrowserConfigurator = config => {\n  shell.exec(`defaults write -app Safari DownloadsPath ${path.join(config.projectPath, config.downloads)}`);\n};\n"
  },
  {
    "path": "src/web/cucumber/config.ts",
    "content": "import config from '../../core/config.helper';\nimport { setDefaultTimeout } from 'cucumber';\n\nsetDefaultTimeout(Number(config.timeout) * 1000);\n"
  },
  {
    "path": "src/web/cucumber/hooks/clear-download.hook.ts",
    "content": "import { After, Before } from 'cucumber';\nimport { HookHandler } from './hook.interface';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport config from '../../../core/config.helper';\n\nconst clearDownload = callback => {\n  const files = fs.readdirSync(path.join(config.projectPath, config.downloads)).filter(file => file !== '.gitkeep');\n\n  for (const file of files) {\n    fs.unlinkSync(path.join(config.projectPath, config.downloads, file));\n  }\n\n  callback();\n};\n\nclass ClearDownloadHook implements HookHandler {\n  public initializeHook() {\n    Before('@downloadClearBefore', (scenario, callback) => {\n      clearDownload(callback);\n    });\n\n    After('@downloadClearAfter', (scenario, callback) => {\n      clearDownload(callback);\n    });\n  }\n\n  public getPriority() {\n    return 1;\n  }\n}\n\nexport const clearDownloadHook = new ClearDownloadHook();\n"
  },
  {
    "path": "src/web/cucumber/hooks/clear-variables.hook.ts",
    "content": "import { Before } from 'cucumber';\nimport { HookHandler } from './hook.interface';\nimport userProvider from '../../user-provider.helper';\nimport variableStore from '../../variable-store.helper';\n\nclass ClearVariablesHook implements HookHandler {\n  public initializeHook() {\n    Before(function(scenario, callback) {\n      this.currentUser = null;\n\n      if (typeof this.userProvider === 'undefined') {\n        this.userProvider = userProvider;\n      }\n\n      variableStore.clearVariables();\n\n      callback();\n    });\n  }\n\n  public getPriority() {\n    return 1;\n  }\n}\n\nexport const clearVariablesHook = new ClearVariablesHook();\n"
  },
  {
    "path": "src/web/cucumber/hooks/hook.interface.ts",
    "content": "export interface HookHandler {\n  initializeHook(): void;\n  getPriority(): number;\n}\n"
  },
  {
    "path": "src/web/cucumber/hooks/hooks.ts",
    "content": "import * as hookHandler from './index';\nimport { HookHandler } from './hook.interface';\n\nclass HookHandlers {\n  constructor(\n    private availableHandlers: HookHandler[] = [\n      hookHandler.takeScreenshotHook,\n      hookHandler.reloadFixturesHook,\n      hookHandler.clearDownloadHook,\n      hookHandler.reloadUserHook,\n      hookHandler.clearVariablesHook,\n    ]\n  ) {}\n\n  public addHook(handler: HookHandler): void {\n    this.availableHandlers.push(handler);\n  }\n\n  public initializeHook(): void {\n    const handlers = this.getHooks();\n\n    for (const handler of handlers) {\n      handler.initializeHook();\n    }\n  }\n\n  public getHooks(): HookHandler[] {\n    return this.availableHandlers.sort((handler, otherHandler) => handler.getPriority() - otherHandler.getPriority());\n  }\n}\n\nexport const hookHandlers = new HookHandlers();\n"
  },
  {
    "path": "src/web/cucumber/hooks/index.ts",
    "content": "export * from './take-screenshots.hook';\nexport * from './reload-fixtures.hook';\nexport * from './reload-user.hook';\nexport * from './clear-download.hook';\nexport * from './clear-variables.hook';\n"
  },
  {
    "path": "src/web/cucumber/hooks/reload-fixtures.hook.ts",
    "content": "import { Before } from 'cucumber';\nimport { HookHandler } from './hook.interface';\nimport * as chalk from 'chalk';\nimport parameters from '../../parameters';\nimport fixturesLoader from '../../fixtures/fixtures-loader.helper';\n\nconst logRequestTime = (timeStart) => {\n  const timeDiff = process.hrtime(timeStart);\n\n  console.log(chalk.black.bgYellow('Request took ' + (timeDiff[0] + timeDiff[1] / 1000000000) + ' seconds'));\n};\n\nclass ReloadFixturesHook implements HookHandler {\n  public initializeHook() {\n    Before('@reloadFixtures', (scenario, callback) => {\n      console.log(chalk.black.bgYellow('Reloading fixtures'));\n\n      const timeStart = process.hrtime();\n\n      fixturesLoader\n        .reloadFixtures(parameters.getReloadFixturesEndpoint())\n        .then((response) => {\n          if (response.status === 200) {\n            console.log(chalk.black.bgGreen('Fixtures reloaded'));\n          } else {\n            console.log(chalk.black.bgRed('There was a problem with fixtures reloading. The response is: '), response);\n          }\n\n          logRequestTime(timeStart);\n\n          callback();\n        })\n        .catch((error) => {\n          console.log(chalk.black.bgRed('An error occurred during fixtures reloading: '), error);\n\n          logRequestTime(timeStart);\n\n          callback();\n        });\n    });\n  }\n\n  public getPriority() {\n    return 2;\n  }\n}\n\nexport const reloadFixturesHook = new ReloadFixturesHook();\n"
  },
  {
    "path": "src/web/cucumber/hooks/reload-user.hook.ts",
    "content": "import { After } from 'cucumber';\nimport { HookHandler } from './hook.interface';\n\nclass ReloadUserHook implements HookHandler {\n  public initializeHook() {\n    After('@reloadUsers', function(scenario, callback) {\n      if (this.currentUser !== null) {\n        this.userProvider.lockUser(this.currentUser.account, this.currentUser.type);\n      }\n\n      callback();\n    });\n  }\n\n  public getPriority() {\n    return 1;\n  }\n}\n\nexport const reloadUserHook = new ReloadUserHook();\n"
  },
  {
    "path": "src/web/cucumber/hooks/take-screenshots.hook.ts",
    "content": "import { HookHandler } from './hook.interface';\nimport config from '../../../core/config.helper';\nimport { After } from 'cucumber';\n\nconst takeScreenshot = scenario => {\n  return browser.takeScreenshot().then(\n    base64png => {\n      scenario.attach(new Buffer(base64png, 'base64'), 'image/png');\n      return Promise.resolve();\n    },\n    () => Promise.resolve()\n  );\n};\n\nconst clearCookiesAndLocalStorage = callback => {\n  let cookiesFunc = () => Promise.resolve(true);\n\n  if (config.clearCookiesAfterScenario) {\n    cookiesFunc = () => protractor.browser.manage().deleteAllCookies();\n  }\n\n  let localStorageFunc = () => Promise.resolve(true);\n  if (config.clearLocalStorageAfterScenario) {\n    localStorageFunc = () => protractor.browser.executeScript('window.localStorage.clear();');\n  }\n\n  browser\n    .wait(\n      cookiesFunc()\n        .then(localStorageFunc)\n        .catch(() => false),\n      config.waitForPageTimeout * 1000\n    )\n    .then(() => {\n      protractor.browser.ignoreSynchronization = config.type === 'otherWeb';\n      callback();\n    });\n};\n\nclass TakeScreenshotHook implements HookHandler {\n  public initializeHook() {\n    return After(function(scenario, callback) {\n      if (scenario.result.status !== 'passed') {\n        takeScreenshot(this).then(() => {\n          clearCookiesAndLocalStorage(callback);\n        });\n      } else {\n        clearCookiesAndLocalStorage(callback);\n      }\n    });\n  }\n\n  public getPriority() {\n    return 1;\n  }\n}\n\nexport const takeScreenshotHook = new TakeScreenshotHook();\n"
  },
  {
    "path": "src/web/cucumber/hooks.ts",
    "content": "import { hookHandlers } from './hooks/hooks';\n\nhookHandlers.initializeHook();\n"
  },
  {
    "path": "src/web/cucumber/wait-for-condition.helper.ts",
    "content": "import config from '../../core/config.helper';\nconst globalTimeout = parseInt(config.elementsVisibilityTimeout) * 1000;\n\nexport const waitForCondition = (condition, timeout) => {\n  return element => {\n    if (element instanceof protractor.ElementArrayFinder) {\n      return browser.wait(protractor.ExpectedConditions[condition](element.first()), timeout);\n    }\n\n    return browser.wait(protractor.ExpectedConditions[condition](element), timeout);\n  };\n};\n\nexport const waitForVisibilityOf = element => {\n  return waitForCondition('visibilityOf', globalTimeout)(element);\n};\n\nexport const waitForInvisibilityOf = element => {\n  return waitForCondition('invisibilityOf', globalTimeout)(element);\n};\n"
  },
  {
    "path": "src/web/fixtures/fixtures-loader.helper.ts",
    "content": "import fetch from 'node-fetch';\n\nconst FixturesLoader = {\n  reloadFixtures(endpoint) {\n    return fetch(endpoint);\n  },\n};\n\nexport default FixturesLoader;\n"
  },
  {
    "path": "src/web/fs/download-checker.helper.ts",
    "content": "import * as fs from 'fs';\nimport * as path from 'path';\nimport config from '../../core/config.helper';\n\nconst DownloadChecker = {\n  wasDownloaded(expectedFileName) {\n    return browser.driver.wait(() => {\n      return fs.existsSync(path.join(config.projectPath, config.downloads, expectedFileName));\n    }, config.downloadTimeout * 1000);\n  },\n};\n\nexport default DownloadChecker;\n"
  },
  {
    "path": "src/web/fs/file-manager.helper.ts",
    "content": "import * as fs from 'fs';\nimport * as xlsx from 'node-xlsx';\nimport * as path from 'path';\nimport config from '../../core/config.helper';\n\nconst FileManager = {\n  wasDownloaded(expectedFileName) {\n    return browser.driver.wait(() => {\n      return fs.existsSync(path.join(config.projectPath, config.downloads, expectedFileName));\n    }, config.downloadTimeout * 1000);\n  },\n\n  parseXLS(expectedFileName) {\n    return xlsx.parse(path.join(config.projectPath, config.downloads, expectedFileName))[0].data;\n  },\n};\n\nexport default FileManager;\n"
  },
  {
    "path": "src/web/parallel/chunk-specs.helper.spec.ts",
    "content": "import { chunkSpecs } from './chunk-specs.helper';\n\nconst allSpecs = [\n  '/Users/user/Kakunin/functional-tests/features/content/operations_on_stored_variables.feature',\n  '/Users/user/Kakunin/functional-tests/features/content/validate_tabular_data.feature',\n  '/Users/user/Kakunin/functional-tests/features/content/wait_for_element_dissapear.feature',\n  '/Users/user/Kakunin/functional-tests/features/drag-and-drop/operations_on_elements.feature',\n  '/Users/user/Kakunin/functional-tests/features/forms/fill_and_check_form.feature',\n  '/Users/user/Kakunin/functional-tests/features/matchers/match_current_date.feature',\n  '/Users/user/Kakunin/functional-tests/features/navigation/navigate_to_given_page.feature',\n  '/Users/user/Kakunin/functional-tests/features/pages/verify_displayed_page.feature',\n  '/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_form.feature',\n  '/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_table.feature',\n];\n\ndescribe('Chunk specs', () => {\n  it('returns all specs as one list as the pattern was not specified', () => {\n    expect(chunkSpecs({}, allSpecs, 1, 1)).toEqual([\n      ['/Users/user/Kakunin/functional-tests/features/content/operations_on_stored_variables.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/content/validate_tabular_data.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/content/wait_for_element_dissapear.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/drag-and-drop/operations_on_elements.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/forms/fill_and_check_form.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/matchers/match_current_date.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/navigation/navigate_to_given_page.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/pages/verify_displayed_page.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_form.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_table.feature'],\n    ]);\n  });\n\n  it('returns chucked specs for one pattern', () => {\n    expect(chunkSpecs({ pattern: 'features/content' }, allSpecs, 1, 1)).toEqual([\n      [\n        '/Users/user/Kakunin/functional-tests/features/content/operations_on_stored_variables.feature',\n        '/Users/user/Kakunin/functional-tests/features/content/validate_tabular_data.feature',\n        '/Users/user/Kakunin/functional-tests/features/content/wait_for_element_dissapear.feature',\n      ],\n    ]);\n  });\n\n  it('returns chucked specs by default because the pattern is boolean - true', () => {\n    expect(chunkSpecs({ pattern: true }, allSpecs, 1, 1)).toEqual([\n      ['/Users/user/Kakunin/functional-tests/features/content/operations_on_stored_variables.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/content/validate_tabular_data.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/content/wait_for_element_dissapear.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/drag-and-drop/operations_on_elements.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/forms/fill_and_check_form.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/matchers/match_current_date.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/navigation/navigate_to_given_page.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/pages/verify_displayed_page.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_form.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_table.feature'],\n    ]);\n  });\n\n  it('returns chucked specs by default because the pattern is boolean - false', () => {\n    expect(chunkSpecs({ pattern: false }, allSpecs, 1, 1)).toEqual([\n      ['/Users/user/Kakunin/functional-tests/features/content/operations_on_stored_variables.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/content/validate_tabular_data.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/content/wait_for_element_dissapear.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/drag-and-drop/operations_on_elements.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/forms/fill_and_check_form.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/matchers/match_current_date.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/navigation/navigate_to_given_page.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/pages/verify_displayed_page.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_form.feature'],\n      ['/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_table.feature'],\n    ]);\n  });\n\n  it('returns chunked specs by default as the pattern was not specified', () => {\n    expect(chunkSpecs({}, allSpecs, 2, 2)).toEqual([\n      [\n        '/Users/user/Kakunin/functional-tests/features/content/operations_on_stored_variables.feature',\n        '/Users/user/Kakunin/functional-tests/features/content/validate_tabular_data.feature',\n      ],\n      [\n        '/Users/user/Kakunin/functional-tests/features/content/wait_for_element_dissapear.feature',\n        '/Users/user/Kakunin/functional-tests/features/drag-and-drop/operations_on_elements.feature',\n      ],\n      [\n        '/Users/user/Kakunin/functional-tests/features/forms/fill_and_check_form.feature',\n        '/Users/user/Kakunin/functional-tests/features/matchers/match_current_date.feature',\n      ],\n      [\n        '/Users/user/Kakunin/functional-tests/features/navigation/navigate_to_given_page.feature',\n        '/Users/user/Kakunin/functional-tests/features/pages/verify_displayed_page.feature',\n      ],\n      [\n        '/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_form.feature',\n        '/Users/user/Kakunin/functional-tests/features/wait-for-elements/wait_for_table.feature',\n      ],\n    ]);\n  });\n\n  it('returns chunked specs by two pattern', () => {\n    expect(chunkSpecs({ pattern: 'features/content,features/forms' }, allSpecs, 2, 2)).toEqual(\n      expect.arrayContaining([\n        [\n          '/Users/user/Kakunin/functional-tests/features/content/operations_on_stored_variables.feature',\n          '/Users/user/Kakunin/functional-tests/features/content/validate_tabular_data.feature',\n          '/Users/user/Kakunin/functional-tests/features/content/wait_for_element_dissapear.feature',\n        ],\n        ['/Users/user/Kakunin/functional-tests/features/forms/fill_and_check_form.feature'],\n      ])\n    );\n  });\n\n  it('returns error as the number of instances is higher than given patterns', () => {\n    expect(() => {\n      chunkSpecs({ pattern: 'features/content' }, allSpecs, 4, 3);\n    }).toThrow('Number of the specified patterns is different than number of instances!');\n  });\n\n  it('returns error as the number of instances is lower than given patterns', () => {\n    expect(() => {\n      chunkSpecs({ pattern: 'features/forms,features/navigation,features/wait-for-elements' }, allSpecs, 2, 2);\n    }).toThrow('Number of the specified patterns is different than number of instances!');\n  });\n});\n"
  },
  {
    "path": "src/web/parallel/chunk-specs.helper.ts",
    "content": "import * as _ from 'lodash';\n\nexport const chunkSpecs = (commandArgs, allSpecs, expectedArrayLength, numberOfInstances) => {\n  if (commandArgs.pattern !== undefined && typeof commandArgs.pattern !== 'boolean') {\n    const patterns = commandArgs.pattern.split(',');\n    const chunkedSpecs = [];\n\n    if (patterns.length !== numberOfInstances) {\n      throw new Error('Number of the specified patterns is different than number of instances!');\n    }\n\n    for (const pattern of patterns) {\n      chunkedSpecs.push(allSpecs.filter(spec => spec.match(new RegExp(pattern))));\n    }\n\n    return chunkedSpecs;\n  }\n\n  return _.chunk(allSpecs, expectedArrayLength);\n};\n"
  },
  {
    "path": "src/web/parallel/prepare-browser-instance-specs.helper.ts",
    "content": "import * as _ from 'lodash';\n\nexport const prepareBrowserInstance = (browserConfig, specs) => {\n  const instance = _.cloneDeep(browserConfig);\n  instance.specs = specs;\n\n  return instance;\n};\n"
  },
  {
    "path": "src/web/parameters.ts",
    "content": "const Parameters = {\n  getReloadFixturesEndpoint() {\n    const config = this.getConfig();\n\n    return config.fixturesReloadHost;\n  },\n\n  getConfig() {\n    if (typeof process.env.FIXTURES_RELOAD_HOST === 'undefined') {\n      throw new Error('Missing fixtures reload url. Use export FIXTURES_RELOAD_HOST=valid-host for setup.');\n    }\n\n    return {\n      fixturesReloadHost: process.env.FIXTURES_RELOAD_HOST,\n    };\n  },\n};\n\nexport default Parameters;\n"
  },
  {
    "path": "src/web/performance/JSON-performance-report-parser.helper.spec.ts",
    "content": "import JSONPerformanceReportParser from './JSON-performance-report-parser.helper';\n\nconst parser = new JSONPerformanceReportParser('src/tests/reports/performance');\n\ndescribe('JSON performance report parser', () => {\n  it('returns found objects with TTFB and URL values', () => {\n    const fileName = 'performance-report.har';\n    expect(parser.parse(fileName)).toContainEqual({ ttfb: 0, url: 'http://localhost:8080/' });\n  });\n\n  it('returns error message - file contains incorrect data', () => {\n    const fileName = 'incorrect-performance-report.har';\n    expect(() => parser.parse(fileName)).toThrow(`${fileName} contains incorrect data!`);\n  });\n});\n"
  },
  {
    "path": "src/web/performance/JSON-performance-report-parser.helper.ts",
    "content": "import * as fs from 'fs';\n\nconst getReport = (fileName, path) => {\n  return JSON.parse(fs.readFileSync(`${path}/${fileName}`, 'utf8'));\n};\n\nclass JSONPerformanceReportParser {\n  private readonly path: string;\n\n  constructor(path = 'reports/performance') {\n    this.path = path;\n  }\n\n  public parse(fileName) {\n    const reportFile = getReport(fileName, this.path);\n    const requests = reportFile.log.entries.map(item => ({\n      ttfb: item.timings.wait,\n      url: item.request.url,\n    }));\n\n    if (requests.length > 0) {\n      return requests;\n    }\n\n    throw Error(`${fileName} contains incorrect data!`);\n  }\n}\n\nexport default JSONPerformanceReportParser;\n"
  },
  {
    "path": "src/web/performance/time-to-first-byte-analyser.helper.spec.ts",
    "content": "import { create as createAnalyser } from './time-to-first-byte-analyser.helper';\n\nconst myFakeParser: any = {\n  parse: () => {\n    return [\n      { ttfb: 0, url: 'http://localhost:8080/' },\n      { ttfb: 2, url: 'http://localhost:8080/assets/kittens.jpg' },\n      { ttfb: 1, url: 'http://localhost:8080/favicon.ico' },\n      { ttfb: 2, url: 'http://localhost:8080/tabular-data' },\n      { ttfb: 1, url: 'http://localhost:8080/assets/kittens.jpg' },\n    ];\n  },\n};\nconst analyser = createAnalyser(myFakeParser);\n\ndescribe('Time to first byte analyser', () => {\n  it('returns found slow request', () => {\n    const maxTiming = 1; // value to be compared with TTFB\n\n    expect(analyser.checkTiming(myFakeParser, maxTiming)).toEqual([\n      { ttfb: 2, url: 'http://localhost:8080/assets/kittens.jpg' },\n      { ttfb: 2, url: 'http://localhost:8080/tabular-data' },\n    ]);\n  });\n\n  it('returns empty array - no slow requests', () => {\n    const maxTiming = 1000; // bigger than the highest request's TTFB value\n\n    expect(analyser.checkTiming(myFakeParser, maxTiming)).toEqual([]);\n  });\n});\n"
  },
  {
    "path": "src/web/performance/time-to-first-byte-analyser.helper.ts",
    "content": "import JSONPerformanceReportParser from './JSON-performance-report-parser.helper';\n\nclass TimeToFirstByteAnalyser {\n  private reader: any;\n\n  constructor(jsonPerformanceReportParser) {\n    this.reader = jsonPerformanceReportParser;\n  }\n\n  public checkTiming(fileName, maxTiming) {\n    const parsedReport = this.reader.parse(fileName);\n\n    return parsedReport.filter(report => report.ttfb > maxTiming);\n  }\n}\n\nexport const create = (reportParser = new JSONPerformanceReportParser()) => new TimeToFirstByteAnalyser(reportParser);\n"
  },
  {
    "path": "src/web/url-parser.helper.spec.ts",
    "content": "import { isRelativePage, waitForUrlChangeTo } from './url-parser.helper';\n\nconst exampleBaseUrl = 'https://example-base-url.com';\n\ndescribe('URL parser', () => {\n  it('returns false if a path in absolute URL is incorrect - without slash', () => {\n    expect(\n      waitForUrlChangeTo('http://localhost:8080/incorrect-data', 'http://localhost:8080/tabular-data').bind(\n        null,\n        exampleBaseUrl\n      )()\n    ).toEqual(false);\n  });\n\n  it('returns false if a path in absolute URL is incorrect - with slash', () => {\n    expect(\n      waitForUrlChangeTo('http://localhost:8080/incorrect-data/', 'http://localhost:8080/tabular-data').bind(\n        null,\n        exampleBaseUrl\n      )()\n    ).toEqual(false);\n  });\n\n  it('returns false if a host in absolute URL is incorrect - without slash', () => {\n    expect(\n      waitForUrlChangeTo('http://google/incorrect-data', 'http://localhost:8080/tabular-data').bind(\n        null,\n        exampleBaseUrl\n      )()\n    ).toEqual(false);\n  });\n\n  it('returns false if a host path in absolute URL is incorrect - without slash', () => {\n    expect(\n      waitForUrlChangeTo('http://google/tabular-data', 'http://localhost:8080/tabular-data').bind(\n        null,\n        exampleBaseUrl\n      )()\n    ).toEqual(false);\n  });\n\n  it('returns false if a host in absolute URL is incorrect - with slash', () => {\n    expect(\n      waitForUrlChangeTo('http://google/incorrect-data/', 'http://localhost:8080/tabular-data').bind(\n        null,\n        exampleBaseUrl\n      )()\n    ).toEqual(false);\n  });\n\n  it('returns false if a path in relative URL is incorrect - without slash', () => {\n    expect(waitForUrlChangeTo('/incorrect-data', 'http://website/tabular-data').bind(null, exampleBaseUrl)()).toEqual(\n      false\n    );\n  });\n\n  it('returns false if a path in relative URL is incorrect - with slash', () => {\n    expect(\n      waitForUrlChangeTo('/incorrect-data/', 'http://website.com/tabular-data').bind(null, 'http://incorrect.com')()\n    ).toEqual(false);\n  });\n\n  it('returns empty object if a page URL and the current URL are the same - absolute URL without slash', () => {\n    expect(\n      waitForUrlChangeTo('http://localhost:8080/tabular-data', 'http://localhost:8080/tabular-data').bind(\n        null,\n        exampleBaseUrl\n      )()\n    ).toEqual({});\n  });\n\n  it('returns empty object if a page URL and the current URL are the same - absolute URL with slash', () => {\n    expect(\n      waitForUrlChangeTo('http://localhost:8080/tabular-data/', 'http://localhost:8080/tabular-data').bind(\n        null,\n        exampleBaseUrl\n      )()\n    ).toEqual({});\n  });\n\n  it('returns empty object if a page URL and the current URL paths are the same - relative URL without slash', () => {\n    expect(\n      waitForUrlChangeTo('/tabular-data', 'http://localhost:8080/tabular-data').bind(null, 'http://localhost:8080')()\n    ).toEqual({});\n  });\n\n  it('returns empty object if a page URL and the current URL paths are the same - relative URL with slash', () => {\n    expect(\n      waitForUrlChangeTo('/tabular-data/', 'http://localhost:8080/tabular-data').bind(null, 'http://localhost:8080')()\n    ).toEqual({});\n  });\n\n  it('returns false if a page URL and the current URL paths are the same but hosts are different - relative URL without slash', () => {\n    expect(\n      waitForUrlChangeTo('/tabular-data', 'http://localhost:8080/tabular-data').bind(null, 'http://google.pl')()\n    ).toEqual(false);\n  });\n\n  it('returns false if a page URL and the current URL paths are the same but hosts are different - relative URL with slash', () => {\n    expect(\n      waitForUrlChangeTo('/tabular-data/', 'http://localhost:8080/tabular-data').bind(null, 'http://google.pl')()\n    ).toEqual(false);\n  });\n\n  it('returns false if a baseUrl is different than the current one - page URL with slash', () => {\n    expect(waitForUrlChangeTo('/', 'https://google.pl/new').bind(null, 'https://google.pl')()).toEqual(false);\n  });\n\n  it('returns false if a baseUrl path is different than the current one - empty URL in page', () => {\n    expect(waitForUrlChangeTo('', 'https://google.pl/new').bind(null, 'https://google.pl')()).toEqual(false);\n  });\n\n  it('returns empty object if a baseUrl and the current one are the same - empty URL in page', () => {\n    expect(waitForUrlChangeTo('', 'http://localhost:8080').bind(null, 'http://localhost:8080')()).toEqual({});\n  });\n\n  it('returns false if a baseUrl is different than the current one - empty URL in page', () => {\n    expect(waitForUrlChangeTo('/', 'https://google.pl').bind(null, 'https://google.com')()).toEqual(false);\n  });\n\n  it('returns object with properties defined in a page URL - one wildcard', () => {\n    expect(\n      waitForUrlChangeTo('https://google.com/:name', 'https://google.com/janek').bind(null, exampleBaseUrl)()\n    ).toEqual({ name: 'janek' });\n  });\n\n  it('returns object with properties defined in a page URL - one wildcard inside a long URL', () => {\n    expect(\n      waitForUrlChangeTo(\n        'https://google.com/account/:username/settings/display',\n        'https://google.com/account/janek/settings/display'\n      ).bind(null, exampleBaseUrl)()\n    ).toEqual({ username: 'janek' });\n  });\n\n  it('returns false if a host is incorrect - one wildcard in relative path', () => {\n    expect(\n      waitForUrlChangeTo('/account/settings/:userType', 'https://incorrect-host/account/settings/admin').bind(\n        null,\n        'https://google.com'\n      )()\n    ).toEqual(false);\n  });\n\n  it('returns false if a URL is incorrect - one wildcard in relative path', () => {\n    expect(\n      waitForUrlChangeTo('/account/settings/:userType/something', 'https://incorrect-host/account/settings/admin').bind(\n        null,\n        'https://google.com'\n      )()\n    ).toEqual(false);\n  });\n\n  it('returns false if a URL is incorrect - one wildcard in absolute path', () => {\n    expect(\n      waitForUrlChangeTo(\n        'https://incorrect-host/account/settings/:userType/something',\n        'https://incorrect-host/account/settings/admin'\n      ).bind(null, exampleBaseUrl)()\n    ).toEqual(false);\n  });\n\n  it('returns object with properties defined in a page URL - one wildcard in relative path', () => {\n    expect(\n      waitForUrlChangeTo('/account/settings/:userType', 'https://google.com/account/settings/user').bind(\n        null,\n        'https://google.com'\n      )()\n    ).toEqual({ userType: 'user' });\n  });\n\n  it('returns false if the URL is absolute - http without path', () => {\n    expect(isRelativePage('http://google.com')).toEqual(false);\n  });\n\n  it('returns false if the URL is absolute - https without path', () => {\n    expect(isRelativePage('https://google.com')).toEqual(false);\n  });\n\n  it('returns false if the URL is absolute - http with path', () => {\n    expect(isRelativePage('http://google.com/with-path')).toEqual(false);\n  });\n\n  it('returns false if the URL is absolute - https with parameter', () => {\n    expect(isRelativePage('https://google.com/:param/with-path')).toEqual(false);\n  });\n\n  it('returns true if the URL is relative', () => {\n    expect(isRelativePage('/with-path')).toEqual(true);\n  });\n\n  it('returns true if the URL is relative - with parameter', () => {\n    expect(isRelativePage('/:path-with-parameter')).toEqual(true);\n  });\n\n  it('returns true if the URL contains only slash', () => {\n    expect(isRelativePage('/')).toEqual(true);\n  });\n\n  it('returns true if the URL is empty', () => {\n    expect(isRelativePage('')).toEqual(true);\n  });\n});\n"
  },
  {
    "path": "src/web/url-parser.helper.ts",
    "content": "import * as Url from 'url';\n\nconst extractDomain = url => Url.parse(url).host;\nconst extractUrl = url => Url.parse(url).pathname;\nconst normalizeUrl = url => {\n  if (url.length === 0) {\n    return extractUrl('/');\n  }\n\n  if (url[url.length - 1] === '/' && url.length > 1) {\n    return extractUrl(url.substr(0, url.length - 1));\n  }\n\n  return extractUrl(url);\n};\n\nconst compareUrls = (urlSplit, baseUrlSplit) => {\n  const resultParameters = {};\n\n  for (const i in urlSplit) {\n    if (urlSplit.hasOwnProperty(i) && baseUrlSplit.hasOwnProperty(i)) {\n      const template = baseUrlSplit[i];\n      const actual = urlSplit[i];\n\n      if (template.startsWith(':')) {\n        resultParameters[template.substr(1)] = actual;\n      } else if (template !== actual) {\n        return false;\n      }\n    }\n  }\n\n  return resultParameters;\n};\n\nexport const isRelativePage = url => {\n  return url === '' || url[0] === '/';\n};\n\nexport const waitForUrlChangeTo = (newUrl, currentUrl) => {\n  return baseUrl => {\n    const pageUrl = Url.resolve(baseUrl, newUrl);\n    const pageDomain = extractDomain(pageUrl);\n    const currentUrlDomain = extractDomain(currentUrl);\n\n    if (pageDomain !== currentUrlDomain) {\n      return false;\n    }\n\n    const urlSplit = normalizeUrl(currentUrl).split('/');\n    const pageUrlSplit = normalizeUrl(pageUrl).split('/');\n\n    if (urlSplit.length !== pageUrlSplit.length) {\n      return false;\n    }\n\n    return compareUrls(urlSplit, pageUrlSplit);\n  };\n};\n"
  },
  {
    "path": "src/web/user-provider.helper.ts",
    "content": "import config from '../core/config.helper';\nconst accounts = config.accounts;\n\nconst userProvider = {\n  getUser(userType) {\n    const user = accounts[userType];\n\n    if (user.accounts.length > 1) {\n      const usedAccounts = user.accounts.filter(account => account.used);\n\n      if (usedAccounts.length === user.accounts.length) {\n        user.accounts.map(account => ({\n          ...account,\n          used: false,\n        }));\n      }\n\n      return user.accounts.find(account => !account.used);\n    }\n\n    return user.accounts[0];\n  },\n\n  lockUser(user, userType) {\n    if (accounts[userType].accounts.length > 1) {\n      accounts[userType].accounts.forEach((account, index) => {\n        if (account.email === user.email) {\n          accounts[userType].accounts[index].used = true;\n        }\n      });\n    }\n  },\n};\n\nexport default userProvider;\n"
  },
  {
    "path": "src/web/variable-store.helper.spec.ts",
    "content": "import VariableStore from './variable-store.helper';\n\ndescribe('Variable store', () => {\n  it('returns empty list of stored variables after clear', () => {\n    VariableStore.variables = [\n      {\n        name: 'newStoredVariable',\n        value: 'example-variable-content',\n      },\n      {\n        name: 'newStoredVariableTwo',\n        value: 'example-variable-content-two',\n      },\n    ];\n\n    VariableStore.clearVariables();\n    expect(VariableStore.variables).toEqual([]);\n  });\n\n  it('returns array which contains newly stored variable', () => {\n    VariableStore.variables = [];\n    VariableStore.storeVariable('newStoredVariable', 'example-variable-content');\n\n    expect(VariableStore.variables).toEqual(\n      expect.arrayContaining([\n        {\n          name: 'newStoredVariable',\n          value: 'example-variable-content',\n        },\n      ])\n    );\n  });\n\n  it('throws error that the variable already exists', () => {\n    VariableStore.variables = [\n      {\n        name: 'newStoredVariable',\n        value: 'example-variable-content',\n      },\n    ];\n\n    expect(() => {\n      VariableStore.storeVariable('newStoredVariable', 'example-variable-content');\n    }).toThrow('Variable newStoredVariable is stored already');\n  });\n\n  it('returns updated array of stored variables', () => {\n    VariableStore.variables = [\n      {\n        name: 'newStoredVariable',\n        value: 'example-variable-content',\n      },\n    ];\n\n    VariableStore.updateVariable('newStoredVariable', 'updated variable');\n    expect(VariableStore.variables).toEqual(\n      expect.arrayContaining([\n        {\n          name: 'newStoredVariable',\n          value: 'updated variable',\n        },\n      ])\n    );\n  });\n\n  it('throws error that the variable cannot be updated because does not exist', () => {\n    VariableStore.variables = [];\n\n    expect(() => {\n      VariableStore.updateVariable('newStoredVariable', 'updated variable');\n    }).toThrow('Variable newStoredVariable does not exist');\n  });\n\n  it('returns value from the stored variable', () => {\n    VariableStore.variables = [\n      {\n        name: 'newStoredVariable',\n        value: 'example-variable-content',\n      },\n    ];\n\n    expect(VariableStore.getVariableValue('newStoredVariable')).toEqual('example-variable-content');\n  });\n\n  it('throws error that the value cannot be displayed because does not exist', () => {\n    VariableStore.variables = [\n      {\n        name: 'newStoredVariable',\n        value: 'example-variable-content',\n      },\n    ];\n\n    expect(() => {\n      VariableStore.getVariableValue('unavailableVariable');\n    }).toThrow('Variable unavailableVariable was not stored');\n  });\n\n  it('returns false when variable was not stored', () => {\n    VariableStore.variables = [];\n\n    expect(VariableStore.isStored('newStoredVariable')).toEqual(false);\n  });\n\n  it('returns true when variable was stored', () => {\n    VariableStore.variables = [\n      {\n        name: 'newStoredVariable',\n        value: 'example-variable-content',\n      },\n    ];\n\n    expect(VariableStore.isStored('newStoredVariable')).toEqual(true);\n  });\n\n  it('returns value with replaced variable with text matcher prefix', () => {\n    VariableStore.variables = [\n      {\n        name: 'newStoredVariable',\n        value: 'example-variable-content',\n      },\n    ];\n\n    expect(VariableStore.replaceTextVariables('t:v:newStoredVariable')).toEqual('t:example-variable-content');\n  });\n\n  it('returns value with replaced variable with only variableStore prefix', () => {\n    VariableStore.variables = [\n      {\n        name: 'newStoredVariable',\n        value: 'example-variable-content',\n      },\n    ];\n\n    expect(VariableStore.replaceTextVariables('v:newStoredVariable')).toEqual('example-variable-content');\n  });\n\n  it('returns the same value if there is no variable prefix - text matcher', () => {\n    VariableStore.variables = [];\n\n    expect(VariableStore.replaceTextVariables('t:some random text')).toEqual('t:some random text');\n  });\n\n  it('returns the same value if there is no variable prefix - regex matcher', () => {\n    VariableStore.variables = [];\n\n    expect(VariableStore.replaceTextVariables('r:notEmpty')).toEqual('r:notEmpty');\n  });\n\n  it('returns full text if there is no stored variable', () => {\n    VariableStore.variables = [];\n\n    expect(VariableStore.replaceTextVariables('t:v:unavailableVariable')).toEqual('t:v:unavailableVariable');\n  });\n});\n"
  },
  {
    "path": "src/web/variable-store.helper.ts",
    "content": "export class VariableStore {\n  constructor(public variables: any[] = []) {}\n\n  public storeVariable(name: string, value: any): void {\n    const foundVariable = this.variables.find(variable => variable.name === name);\n\n    if (typeof foundVariable !== 'undefined') {\n      throw new Error(`Variable ${name} is stored already`);\n    }\n\n    this.variables.push({ name, value });\n  }\n\n  public updateVariable(name: string, value: any): void {\n    const foundVariable = this.variables.find(variable => variable.name === name);\n\n    if (typeof foundVariable === 'undefined') {\n      throw new Error(`Variable ${name} does not exist.`);\n    }\n\n    this.variables.push({ name, value });\n  }\n\n  public getVariableValue(name: string): any {\n    const foundVariable = this.variables.find(variable => variable.name === name);\n\n    if (typeof foundVariable === 'undefined') {\n      throw new Error(`Variable ${name} was not stored`);\n    }\n\n    return foundVariable.value;\n  }\n\n  public isStored(name: string): boolean {\n    const foundVariable = this.variables.find(variable => variable.name === name);\n\n    return typeof foundVariable !== 'undefined';\n  }\n\n  public clearVariables(): void {\n    this.variables = [];\n  }\n\n  public replaceTextVariables(text: string): any {\n    let newText = text;\n    const variableNames = this.variables.map(variable => variable.name);\n\n    for (const variableNameIndex in variableNames) {\n      if (variableNames.hasOwnProperty(variableNameIndex)) {\n        const variableName = variableNames[variableNameIndex];\n\n        if (newText.indexOf(variableName) > -1) {\n          newText = text.replace(`v:${variableName}`, this.getVariableValue(variableName));\n          break;\n        }\n      }\n    }\n\n    return newText;\n  }\n}\n\nexport default new VariableStore();\n"
  },
  {
    "path": "templates/example.feature",
    "content": "Feature: Example feature file\n    Scenario: Example scenario\n        When I visit the \"page\" page\n        And I generate random \"name\" as \"myName\"\n        Then my matcher \"e:name\" matches \"v:myName\"\n        And my matcher \"e:name\" matches \"Bob\"\n"
  },
  {
    "path": "templates/generator.js",
    "content": "const { generators } = require('kakunin');\n\nclass Generator {\n  isSatisfiedBy(name) {\n    return name === 'name';\n  }\n\n  generate() {\n    const names = [\n      'Bob',\n      'John',\n      'Paul'\n    ];\n\n    return Promise.resolve(names[Math.floor(Math.random() * names.length)]);\n  }\n}\n\ngenerators.addGenerator(new Generator());\n"
  },
  {
    "path": "templates/hook.js",
    "content": "const { hookHandlers, Before } = require('kakunin');\n\nclass TestHook {\n  initializeHook() {\n    Before(() => {\n      console.log('Standard hook');\n    });\n  }\n\n  getPriority() {\n    return 990;\n  }\n}\n\nhookHandlers.addHook(new TestHook());\n"
  },
  {
    "path": "templates/login.js",
    "content": "const { Given } = require('kakunin');\n\nGiven(/^I am logged in as a \"([^\"]*)$/, async function(user) {\n  this.currentUser = {\n    account: this.userProvider.getUser(user),\n    type: user,\n  };\n\n  const mainPage = browser.page.main;\n  const loginPage = browser.page.login;\n\n  await mainPage.visit();\n  await mainPage.waitForVisibilityOf('login');\n  await mainPage.click('login');\n  await loginPage.login(this.currentUser.account.email, this.currentUser.account.password);\n  await mainPage.waitForInvisibilityOf('login');\n\n  this.currentPage = mainPage;\n});\n"
  },
  {
    "path": "templates/matcher.js",
    "content": "const { regexBuilder, matchers } = require('kakunin');\n\nconst ExampleMatcher = {\n  isSatisfiedBy: function (prefix, name) {\n    return prefix === 'e';\n  },\n\n  match: function (element, regexName) {\n    const regex = regexBuilder.buildRegex(`r:${regexName}`);\n\n    return regex.test(element);\n  }\n};\n\nmatchers.addMatcher(ExampleMatcher);\n"
  },
  {
    "path": "templates/page.js",
    "content": "const { BasePage } = require('kakunin');\n\nclass ExamplePage extends BasePage {\n  constructor() {\n    super();\n\n    this.url = '/';\n  }\n}\n\nmodule.exports = ExamplePage;\n"
  },
  {
    "path": "templates/regex.js",
    "content": "module.exports = {\n  name: '(Bob|John|Paul)'\n};\n"
  },
  {
    "path": "templates/steps.js",
    "content": "const { matchers, variableStore, Then } = require('kakunin');\n\nThen(/^my matcher \"([^\"]*)\" matches \"([^\"]*)\"$/, function (matcher, text) {\n  return expect(matchers.match(variableStore.replaceTextVariables(text), matcher)).toBe(true);\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    \"module\": \"commonjs\",\n    \"allowSyntheticDefaultImports\": false,\n    \"outDir\": \"dist\",\n    \"noUnusedLocals\": true,\n    \"noImplicitAny\": false,\n    \"removeComments\": false\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"**/*.spec.ts\",\n    \"dist/**\"\n  ],\n  \"include\": [\n    \"./src/kakunin.d.ts\",\n    \"./src/**/*.ts\"\n  ]\n}\n"
  },
  {
    "path": "tsconfig.test.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"target\": \"es6\"\n  }\n}"
  },
  {
    "path": "tslint.json",
    "content": "{\n  \"defaultSeverity\": \"error\",\n  \"extends\": [\n    \"tslint:recommended\",\n    \"tslint-config-prettier\",\n    \"tslint-sonarts\"\n  ],\n  \"linterOptions\": {\n    \"exclude\": [\n      \"**/*.spec.ts\",\n      \"**/*.d.ts\"\n    ]\n  },\n  \"jsRules\": {},\n  \"rules\": {\n    \"no-extra-semicolon\": false,\n    \"no-empty-interface\": false,\n    \"object-literal-sort-keys\": false,\n    \"radix\": false,\n    \"interface-name\": [true, \"never-prefix\"],\n    \"ordered-imports\": false,\n    \"no-duplicate-string\": false,\n    \"variable-name\": [true, \"ban-keywords\", \"allow-leading-underscore\", \"allow-pascal-case\"],\n    \"interface-over-type-literal\": false,\n    \"no-angle-bracket-type-assertion\": false,\n    \"max-union-size\": false,\n    \"no-identical-functions\": false,\n    \"no-console\": false,\n    \"no-var-requires\": false,\n    \"cognitive-complexity\": false,\n    \"no-big-function\": false\n  },\n  \"rulesDirectory\": []\n}\n"
  },
  {
    "path": "website/README.md",
    "content": "<h1>\n  <p align=\"center\">\n    <img src=\"../data/kakunin_logo.png\" alt=\"kakunin.png\" width=\"550\"/>\n  </p>\n</h1>\n\n<p align=\"center\">\n   <img src=\"../data/travis.png\" alt=\"travis.png\" width=\"25\" />\n   Current travis build:\n   <a href=\"https://travis-ci.org/TheSoftwareHouse/Kakunin\"><img src=\"https://travis-ci.org/TheSoftwareHouse/Kakunin.svg?branch=master\" alt=\"build status\" height=\"18\"></a>\n  &emsp;\n  <img src=\"../data/npm.png\" alt=\"npm.png\" width=\"25\"/> \n  Current npm version:\n  <a href=\"https://badge.fury.io/js/kakunin\"><img src=\"https://badge.fury.io/js/kakunin.svg\" alt=\"npm version\" height=\"18\"></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#getting-started-with-docusaurus\">Getting started</a> •\n  <a href=\"#content-management\">Content mangment</a> •\n  <a href=\"#versifying\">Versifying</a> •\n  <a href=\"#building-application\">Building application</a> •\n  <a href=\"#publishing\">Publishing</a> •  \n  <a href=\"#full-documentation\">Docs</a> •\n</p>\n\n<p align=\"center\">\n     <img src=\"../data/pageObjectFeature.gif\" alt=\"pageObjectFeature.gif\"/>\n</p>\n\n<h1>\n</h1>\n\n# Getting started with Docusaurus\n\n1. Make sure all the dependencies for the website are installed:\n\n```sh\n# Install dependencies\n$ yarn\n```\n2. Run documentation in local environment. Change directory into `website` folder:\n\n```sh\n# Start the site\n$ yarn start\n```\n\n# Directory Structure\n\nProject file structure look like this:\n\n```\nKakunin/\n  docs/\n    configuration.md\n    extending.md\n    ...\n  website/\n    core/\n    node_modules/\n    pages/\n    static/\n      css/\n      img/\n    package.json\n    sidebars.json\n    siteConfig.js\n```\n\n# Content management\n## Adding new content to documentation\n\n1. In `docs/` folder add new markdown file `docs/new-markdown-file.md`\n\n2. In created file on top of the document add:\n\n```markdown\n---\nid: new-markdown-file\ntitle: New Markdown File\n---\n\nNew Content...\n```\n \nTitle should be in uppercase - it is displayed in browser tab titile.\nId should be in lowercase - it is used in `website/sidebars.json`.\n\n3. In `website/sidebar.json` add ID of the created markdowns file, into desired array. \n\n```javascript\n{\n  \"docs\": {\n    \"Kakunin\": [\n      \"quickstart\",\n      \"index\",\n      \"configuration\",\n      \"how-it-works\",\n      \"steps\",\n      \"matchers\",\n      \"transformers\",\n      \"cross-browser\",\n      \"parallel-testing\",\n      \"performance-testing\",\n      \"extending\",\n      \"new-markdown-file\"\n    ]\n  }\n}\n\n```\n\n4. Test your site locally to confirm changes.  \n\n\n## Editing an existing docs page\n\n1. To edit file open in `docs` folder open file which should be edited `docs/new-markdown-file.md`\n2. Change content of file\n3. Test your site locally to confirm changes.  \n\n# Versifying\n\nDocusaurus support versifying, right now we started to using this feature from  `2.4.0` Kakunin version.\n\n1. To add new version of documentation open `website/` folder\n2. Run `yarn run version [version]` example `yarn run version 2.4.0-1`\n3. After that in `website/` will be created 2 folders `versioned_docs/` & `versioned_sidebars/`\n4. In `versioned_docs/` will be created folder `version-2.4.0-1` \n5. In `versioned_sidebars/` there will be created json file with changed sidebar `version-2.4.0-sidebars.json`.  \n**In those folders there are only files which was added or changed!**\n6. After that our latest version will be `2.4.0-1`\n\n# Building application\n\n1. To build application in `website/` folder run `yarn build` \n2. After that in `website/build/Kakunin` will be created application for latest version `2.4.0-1`\n\n# Publishing\n\nTo publish changes run: `GIT_USER=<USER> CURRENT_BRANCH=next USE_SSH=true npm run publish-gh-pages` where <USER> is your github user.\n\n# Full Documentation\n\nFull documentation can be found on the [website](https://docusaurus.io/).\n"
  },
  {
    "path": "website/build/Kakunin/css/main.css",
    "content": "a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{border:0;font:inherit;font-size:100%;margin:0;padding:0;vertical-align:baseline}body{color:#24292e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-size:16px;line-height:1.5;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;word-wrap:break-word}*{box-sizing:border-box}b,strong{font-weight:600}em,i{font-style:italic}[type=checkbox]{box-sizing:border-box;padding:0}a,a:hover{color:#2f1666;text-decoration:none}a:active,a:hover{outline-width:0}a:not([href]){color:inherit;text-decoration:none}p{margin-bottom:1em;margin-top:0}h1,h2,h3,h4,h5,h6{color:inherit;font-weight:600;line-height:1.25;margin-bottom:16px;margin-top:1.5em}h1{font-size:32px}h2{font-size:24px}h3{font-size:20px}h4{font-size:16px}h5{font-size:14px}h6{font-size:13.6px}ol,ul{margin-bottom:1em;margin-top:0;padding-left:2em}ol ol,ul ol{list-style-type:lower-roman}ol ol,ol ul,ul ol,ul ul{margin-bottom:0;margin-top:0}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}li{word-wrap:break-all}li>p{margin-top:1em}li+li{margin-top:.25em}img{border-style:none;box-sizing:content-box;max-width:100%}img[align=right]{padding-left:1.25em}img[align=left]{padding-right:1.25em}table{border-collapse:collapse;border-spacing:0;display:block;margin-bottom:16px;margin-top:0;overflow:auto;width:100%}table tr{background-color:transparent;border-top:1px solid #dfe2e5}table tr:nth-child(2n){background-color:#f6f8fa}table td,table th{border:1px solid #dfe2e5;padding:6px 13px}table th{background-color:inherit;font-weight:600}table td,table th{color:inherit}blockquote{color:#6a737d;font-size:16px;margin:0 0 16px;padding:0 1em}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}code{background-color:rgba(27,31,35,.05);border-radius:3px;color:inherit;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:85%;margin:0;padding:3.2px 6.4px}pre{margin-bottom:16px}pre code{background-color:transparent;border:0;display:inline;font-size:85%;line-height:inherit;margin:0;max-width:auto;overflow:visible;padding:0;white-space:pre;word-break:normal;word-wrap:normal}kbd{background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px 0 #c6cbd1;color:#444d56;display:inline-block;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:68.75%;line-height:10px;padding:3px 5px;vertical-align:middle}hr{border:1px solid #dfe2e5;box-sizing:content-box;margin:1.5em 0;overflow:hidden;padding:0}hr:after,hr:before{content:\"\";display:table}hr:after{clear:both}body{background-color:#fff;min-height:100vh;text-rendering:optimizeLegibility}@media only screen and (min-width:736px){body{display:flex;flex-direction:column}}article:after,article:before{content:\"\";display:table}article:after{clear:both}article>:first-child{margin-top:0}article>:last-child{margin-bottom:0}article iframe,article p img{display:block;margin-left:auto;margin-right:auto;max-width:100%}.anchor{display:block;position:relative;top:-80px}.hash-link{line-height:1;margin-left:-20px;opacity:0;padding-right:4px;transition:opacity .3s}.hash-link:hover{opacity:1!important;transition:none}.hash-link .hash-link-icon{vertical-align:middle}.button{border:1px solid #2f1666;border-radius:3px;color:#2f1666;display:inline-block;font-size:14px;font-weight:400;line-height:1.2em;padding:10px;text-decoration:none!important;text-transform:uppercase;transition:background .3s,color .3s}.button:hover{background:#2f1666;color:#fff}h1:hover .hash-link,h2:hover .hash-link,h3:hover .hash-link,h4:hover .hash-link{opacity:.5;transition:none}blockquote{background-color:rgba(255,229,100,.3);border-left:8px solid #ffe564;padding:15px 30px 15px 15px}.wrapper{margin:0 auto;max-width:1100px;padding:0 20px}.wrapper blockquote>p:first-child{padding-top:0}.center{display:block}.center,.homeContainer{text-align:center}.homeContainer .homeWrapper{padding:2em 10px}.homeContainer .homeWrapper .wrapper{margin:0 auto;max-width:900px;padding:0 20px}.homeContainer .homeWrapper .projectLogo img{height:100px;margin-bottom:0}.homeContainer .homeWrapper #project_title{font-size:300%;letter-spacing:-.08em;line-height:1em;margin-bottom:80px}.homeContainer .homeWrapper #project_tagline{font-size:200%;letter-spacing:-.04em;line-height:1em}.projectLogo{display:none;pointer-events:none}.projectLogo img{height:100px;margin-bottom:0}.projectIntro{margin:40px 0}.projectTitle{color:#2f1666;font-size:250%;line-height:1em}.projectTitle>small{display:block;font-weight:400;font-size:50%;line-height:1em;margin:.7em 0 1.3em}@media only screen and (min-width:480px){.projectTitle{font-size:300%;margin:.3em 0}.projectLogo img{height:200px;margin-bottom:10px}.homeContainer .homeWrapper{padding-left:10px;padding-right:10px}}@media only screen and (min-width:736px){.homeContainer .homeWrapper{position:relative}.homeContainer .homeWrapper #inner{max-width:600px;padding-right:40px}}@media only screen and (min-width:1200px){.homeContainer .homeWrapper #inner{max-width:750px}.homeContainer .homeWrapper .projectLogo{align-items:center;bottom:0;display:flex;justify-content:flex-end;left:0;padding:2em 100px 4em;position:absolute;right:0;top:0}.homeContainer .homeWrapper .projectLogo img{height:100%;max-height:250px}}@media only screen and (min-width:1500px){.homeContainer .homeWrapper #inner{max-width:1100px;padding-bottom:40px;padding-top:40px}.wrapper{max-width:1400px}}.mainContainer{flex:1 1 0%;max-width:100%;padding:40px 0}.mainContainer .wrapper{text-align:left}.mainContainer .wrapper .allShareBlock{padding:10px 0}.mainContainer .wrapper .allShareBlock .pluginBlock{margin:12px 0;padding:0}.mainContainer .wrapper .post{position:relative}.mainContainer .wrapper .post.basicPost{margin-top:30px}.mainContainer .wrapper .post .postHeader{margin-bottom:16px}.mainContainer .wrapper .post .postHeaderTitle{margin-top:0;padding:0}.docsContainer .wrapper .post .postHeader:before,.docsContainer .wrapper .post .postHeaderTitle:before{content:\"\";display:block;height:90px;margin-top:-90px;visibility:hidden;pointer-events:none}.mainContainer .wrapper .post .postSocialPlugins{padding-top:1em}.mainContainer .wrapper .post .docPagination{background:#2f1666;bottom:0;left:0;position:absolute;right:0}.mainContainer .wrapper .post .docPagination .pager{display:inline-block;width:50%}.mainContainer .wrapper .post .docPagination .pagingNext{float:right;text-align:right}.mainContainer .wrapper .post .docPagination a{border:none;color:#fff;display:block;padding:4px 12px}.mainContainer .wrapper .post .docPagination a:hover{background-color:#f9f9f9;color:#393939}.mainContainer .wrapper .post .docPagination a .pagerLabel{display:inline}.mainContainer .wrapper .post .docPagination a .pagerTitle{display:none}@media only screen and (min-width:480px){.mainContainer .wrapper .post .docPagination a .pagerLabel{display:none}.mainContainer .wrapper .post .docPagination a .pagerTitle{display:inline}}@media only screen and (min-width:1024px){.mainContainer .wrapper .post{display:block}.mainContainer .wrapper .posts .post{width:100%}}@media only screen and (max-width:1023px){.docsContainer .wrapper .post .postHeader:before,.docsContainer .wrapper .post .postHeaderTitle:before{content:\"\";display:block;height:200px;margin-top:-200px;visibility:hidden;pointer-events:none}}.fixedHeaderContainer{background:#2f1666;color:#fff;min-height:50px;padding:8px 0;position:fixed;width:100%;z-index:9999;transform:translateZ(0)}@media only screen and (min-width:1024px){.fixedHeaderContainer{flex-shrink:0}}.fixedHeaderContainer a{align-items:center;border:0;color:#fff;display:flex;flex-flow:row nowrap;height:34px;z-index:10000}.fixedHeaderContainer header{display:flex;flex-flow:row nowrap;position:relative;text-align:left}.fixedHeaderContainer header img{height:100%;margin-right:10px}.fixedHeaderContainer header .headerTitle{font-size:1.25em;margin:0}.fixedHeaderContainer header .headerTitleWithLogo{display:block;font-size:1.25em;line-height:18px;margin:0;position:relative;z-index:9999}.fixedHeaderContainer header h3{color:#fff;font-size:16px;margin:0 0 0 10px;text-decoration:underline}@media (max-width:480px){.headerTitle{font-size:17px}.headerTitleWithLogo{display:none!important}}.promoSection{display:flex;flex-flow:column wrap;font-size:125%;line-height:1.6em;position:relative;z-index:99}.promoSection .promoRow{padding:10px 0}.promoSection .promoRow .pluginWrapper{display:block}.promoSection .promoRow .pluginWrapper.ghStarWrapper,.promoSection .promoRow .pluginWrapper.ghWatchWrapper{height:28px}.promoSection .promoRow .pluginRowBlock{display:flex;flex-wrap:wrap;justify-content:center;margin:0 -2px}.promoSection .promoRow .pluginRowBlock .pluginWrapper{padding:0 2px}.promoSection .promoRow .pluginRowBlock iframe{margin-left:2px;margin-top:5px}input[type=search]{-moz-appearance:none;-webkit-appearance:none}.navSearchWrapper{align-items:center;align-self:center;display:flex;justify-content:center;padding-left:10px;position:absolute;right:10px;top:10px}.navSearchWrapper:before{border:3px solid #e5e5e5;border-radius:50%;content:\" \";display:block;height:6px;left:15px;position:absolute;top:50%;transform:translateY(-58%);width:6px;z-index:1}.navSearchWrapper:after{background:#e5e5e5;content:\" \";height:7px;left:24px;position:absolute;top:55%;transform:rotate(-45deg);width:3px;z-index:1}.navSearchWrapper .aa-dropdown-menu{background:#f9f9f9;border:3px solid rgba(57,57,57,.25);color:#393939;font-size:14px;left:auto!important;line-height:1.2em;right:0!important}.navSearchWrapper .aa-dropdown-menu .algolia-docsearch-suggestion--category-header{background:#2f1666;color:#fff;font-size:14px;font-weight:400}.navSearchWrapper .aa-dropdown-menu .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight{background-color:#2f1666;color:#fff}.navSearchWrapper .aa-dropdown-menu .algolia-docsearch-suggestion--subcategory-column .algolia-docsearch-suggestion--highlight,.navSearchWrapper .aa-dropdown-menu .algolia-docsearch-suggestion--title .algolia-docsearch-suggestion--highlight{color:#2f1666}.navSearchWrapper .aa-dropdown-menu .algolia-docsearch-suggestion--subcategory-column,.navSearchWrapper .aa-dropdown-menu .algolia-docsearch-suggestion__secondary{border-color:rgba(57,57,57,.3)}input#search_input_react{background-color:rgba(0,0,0,.2);border:none;border-radius:20px;color:#fff;font-size:14px;font-weight:300;line-height:20px;outline:none;padding-left:25px;position:relative;transition:width .5s ease;width:170px}.navSearchWrapper:before{left:24px}.navSearchWrapper:after{left:35px}input#search_input_react:active,input#search_input_react:focus{color:#fff;width:220px}.navigationSlider .slidingNav .navSearchWrapper .algolia-docsearch-footer a{height:auto}@media only screen and (max-width:735px){.navSearchWrapper{width:40%}}input::-moz-placeholder{color:#e5e5e5}input:-ms-input-placeholder{color:#e5e5e5}input::placeholder{color:#e5e5e5}.hljs{padding:1.25rem 1.5rem}.gridBlock{padding:0}.gridBlock>*{box-sizing:border-box}.gridBlock .fourByGridBlock img,.gridBlock .threeByGridBlock img,.gridBlock .twoByGridBlock img{max-width:100%}.gridBlock .gridClear{clear:both}@media only screen and (max-width:735px){.gridBlock .fourByGridBlock{flex:1 0 26%}}@media only screen and (min-width:736px){.gridBlock{display:flex;flex-direction:row;flex-wrap:wrap}.gridBlock>*{margin:0 12px}.gridBlock>:first-child{margin-left:0}.gridBlock>:last-child{margin-right:0}.gridBlock .twoByGridBlock{flex:1 0 40%}.gridBlock .threeByGridBlock{flex:1 0 26%}.gridBlock .fourByGridBlock{flex:1 0 20%}h2+.gridBlock{padding-top:20px}}@media only screen and (min-width:1400px){.gridBlock{display:flex;flex-direction:row;flex-wrap:wrap}}.alignCenter{text-align:center}.alignRight{text-align:right}.imageAlignSide{display:flex;flex-flow:row wrap}.blockImage{max-width:730px}.imageAlignSide .blockImage{flex:0 1 500px;max-width:500px}@media only screen and (max-width:735px){.imageAlignSide .blockImage{display:none}}.imageAlignSide .blockContent{flex:1 1}.imageAlignBottom .blockImage{margin:0 auto 20px;max-width:730px}.imageAlignBottom.alignCenter .blockImage{margin-left:auto;margin-right:auto}.imageAlignTop .blockImage{margin-bottom:20px;max-width:80px}.imageAlignTop.alignCenter .blockImage{margin-left:auto;margin-right:auto}.imageAlignRight .blockImage{margin-left:40px}.imageAlignLeft .blockImage{margin-right:40px}.container .gridBlock .blockContent p{padding:0}.container .wrapper .alignCenter h2{text-align:center}.container .wrapper .imageAlignSide h2{text-align:left}.container .wrapper .imageAlignSide p{margin:0 0 40px;max-width:560px}.highlightBackground{background:rgba(153,66,79,.7);color:#fff}.highlightBackground a{font-weight:800}.container.highlightBackground .wrapper h1,.container.highlightBackground .wrapper h2,.container.highlightBackground .wrapper h3,.container.highlightBackground .wrapper h4,.container.highlightBackground .wrapper h5,.highlightBackground a{border-color:#fff;color:#fff}.lightBackground{background:#f7f7f7}.darkBackground{background:grey;color:#fff}.darkBackground a,.darkBackground code{color:#d6b3b8}.container.darkBackground .wrapper h1,.container.darkBackground .wrapper h2,.container.darkBackground .wrapper h3,.container.darkBackground .wrapper h4,.container.darkBackground .wrapper h5{border-color:#fff;color:#fff}.container.paddingAll{padding:40px}.container.paddingBottom{padding-bottom:80px}.container.paddingLeft{padding-left:40px}.container.paddingRight{padding-right:40px}.container.paddingTop{padding-top:80px}@media only screen and (max-width:735px){.container.paddingBottom{padding-bottom:40px}.container.paddingTop{padding-top:20px}}@media only screen and (max-width:1023px){.responsiveList .blockContent{position:relative}.responsiveList .blockContent>div{padding-left:20px}.responsiveList .blockContent:before{content:\"\\2022\";position:absolute}}.navigationSlider .navSlideout{cursor:pointer;padding-top:4px;position:absolute;right:10px;top:0;transition:top .3s;z-index:101}.navigationSlider .slidingNav{bottom:auto;box-sizing:border-box;left:0;position:fixed;right:0;top:0}.navigationSlider .slidingNav.slidingNavActive{height:auto;padding-top:42px;width:300px}.navigationSlider .slidingNav ul{background:#7731f6;box-sizing:border-box;color:#fff;display:flex;flex-wrap:nowrap;list-style:none;margin-top:50px;padding:0;width:100%}.navigationSlider .slidingNav.slidingNavActive ul{display:block}.navigationSlider .slidingNav ul li{flex:1 1 auto;margin:0;text-align:center;white-space:nowrap}.navigationSlider .slidingNav ul li a{align-items:center;box-sizing:border-box;color:#2f1666;color:inherit;display:flex;font-size:.9em;height:auto;height:50px;justify-content:center;margin:0;padding:10px;transition:background-color .3s}.navigationSlider .slidingNav ul li.siteNavGroupActive>a,.navigationSlider .slidingNav ul li.siteNavItemActive>a,.navigationSlider .slidingNav ul li>a:focus,.navigationSlider .slidingNav ul li>a:hover{background-color:#2f1666}.languages-icon{width:20px}#languages-dropdown{pointer-events:none;position:absolute;width:100%}#languages-dropdown.visible{display:flex}#languages-dropdown.hide{display:none}#languages-dropdown-items{background-color:#2f1666;display:flex;flex-direction:column;min-width:120px;pointer-events:all}#languages li{display:block}.navPusher{left:0;min-height:100%;padding-top:100px;position:relative;z-index:99}.singleRowMobileNav.navPusher{padding-top:50px}.navPusher:after{background:rgba(0,0,0,.4);content:\"\";height:0;opacity:0;position:absolute;right:0;top:0;transition:opacity .5s,width .1s .5s,height .1s .5s;width:0}@media screen and (min-width:1024px){.navPusher{display:flex;flex-direction:column;min-height:calc(100vh - 50px);padding-top:50px}.navPusher,.navPusher>:first-child{flex-grow:1}}.sliderActive .navPusher:after{height:100%;opacity:1;transition:opacity .5s;width:100%;z-index:100}@media only screen and (max-width:1024px){.reactNavSearchWrapper input#search_input_react{background-color:rgba(242,196,178,.25);border:none;border-radius:20px;box-sizing:border-box;color:#393939;font-size:14px;line-height:20px;outline:none;padding-left:38px;position:relative;transition:background-color .2s cubic-bezier(.68,-.55,.265,1.55),width .2s cubic-bezier(.68,-.55,.265,1.55),color .2s ease;width:100%;height:30px}.reactNavSearchWrapper input#search_input_react:active,.reactNavSearchWrapper input#search_input_react:focus{background-color:#2f1666;color:#fff}.reactNavSearchWrapper .algolia-docsearch-suggestion--subcategory-inline{display:none}.reactNavSearchWrapper>span{width:100%}.reactNavSearchWrapper .aa-dropdown-menu{font-size:12px;line-height:2em;padding:0;border-width:1px;min-width:500px}.reactNavSearchWrapper .algolia-docsearch-suggestion__secondary{border-top:none}.aa-suggestions{min-height:140px;max-height:60vh;-webkit-overflow-scrolling:touch;overflow-y:scroll}#languages-dropdown{left:0;top:50px}#languages-dropdown-items{background-color:#2f1666;display:flex;flex-direction:row}}@media only screen and (min-width:1024px){.navSearchWrapper{padding-left:10px;position:relative;right:auto;top:auto}.reactNavSearchWrapper input#search_input_react{height:100%;padding-top:8px;padding-bottom:8px;padding-left:38px}.navSearchWrapper .algolia-autocomplete{display:block}.navigationSlider{height:34px;margin-left:auto;position:relative}.navigationSlider .navSlideout{display:none}.navigationSlider nav.slidingNav{background:none;height:auto;position:relative;right:auto;top:auto;width:auto}.navigationSlider .slidingNav ul{background:none;display:flex;flex-flow:row nowrap;margin:0;padding:0;width:auto}.navigationSlider .slidingNav ul li a{border:0;color:hsla(0,0%,100%,.8);display:flex;font-size:16px;font-size:1em;font-weight:300;height:32px;line-height:1.2em;margin:0;padding:6px 10px}.navigationSlider .slidingNav ul li.siteNavGroupActive a,.navigationSlider .slidingNav ul li.siteNavItemActive a,.navigationSlider .slidingNav ul li a:hover{color:#fff}}@media only screen and (max-width:735px){.navigationSlider .slidingNav ul{overflow-x:auto}.navigationSlider .slidingNav ul::-webkit-scrollbar{display:none}.reactNavSearchWrapper .aa-dropdown-menu{min-width:400px}}@media only screen and (max-width:475px){.reactNavSearchWrapper .aa-dropdown-menu{min-width:300px}}.docMainWrapper .wrapper{padding-left:0;padding-right:0;padding-top:10px}@media only screen and (min-width:1024px){.docMainWrapper{width:100%}.docMainWrapper>*{margin:0 24px}.docMainWrapper>:first-child{margin-left:0}.docMainWrapper>:last-child{margin-right:0}.docMainWrapper .mainContainer{min-width:0}}.edit-page-link{float:right;font-size:10px;font-weight:400;margin-top:3px;text-decoration:none}@media only screen and (max-width:1023px){.edit-page-link{display:none}}.docLastUpdate{font-size:13px;font-style:italic;margin:20px 0;text-align:right}.docs-prevnext{margin:20px 0}.docs-prevnext:after{clear:both;content:\" \";display:table}.docs-next{float:right}.docs-prev{float:left}@media only screen and (max-width:735px){.docs-next{clear:both;float:left}.docs-next,.docs-prev{margin:10px 0}.arrow-next{float:right;margin-left:10px}.arrow-prev{float:left;margin-right:10px}.function-name-prevnext{width:200px;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.hide{display:none}.collapsible{cursor:pointer}.collapsible .arrow{float:right;margin-right:8px;margin-top:-4px;transform:rotate(90deg);transition:transform .2s linear}.collapsible .arrow.rotate{transform:rotate(180deg)}@media only screen and (max-width:1023px){.docsNavContainer{background:#fff;left:0;position:fixed;width:100%;z-index:100}}@media only screen and (min-width:1024px){.docsNavContainer{flex:0 0 240px;height:calc(100vh - 50px);position:sticky;overflow-y:auto;top:50px}}.docsSliderActive.docsNavContainer{box-sizing:border-box;height:100%;-webkit-overflow-scrolling:touch;overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:contain;padding-bottom:50px}.docsNavContainer .toc .navBreadcrumb{background-color:#f1f1f1;box-sizing:border-box;display:flex;flex-flow:row nowrap;font-size:12px;height:48px;overflow:hidden;padding:8px 20px}.docsNavContainer .toc .navWrapper{padding:0}@media only screen and (min-width:1024px){.docsNavContainer .toc .navBreadcrumb{display:none}.navBreadcrumb h2{padding:0 10px}.separateOnPageNav .docsNavContainer{flex:0 0 240px}}.navBreadcrumb a,.navBreadcrumb span{border:0;color:#393939}@media only screen and (max-width:735px){.anchor{top:-144px}}@media only screen and (min-width:1024px){.toc{padding:40px 0}}.toc section{padding:0;position:relative}.toc section .navGroups{display:none;padding:48px 20px 60px}.toc .toggleNav{color:#393939;position:relative}.toc .toggleNav .navToggle{cursor:pointer;height:32px;margin-right:10px;position:relative;text-align:left;width:18px}.hamburger-menu{position:absolute;top:6px;width:100%}.line1,.line2,.line3{width:100%;height:3px;background-color:#393939;margin:3px 0;transition:.4s;border-radius:10px}.docsSliderActive .hamburger-menu{top:12px}.docsSliderActive .line1{position:absolute;top:50%;transform:rotate(-45deg)}.docsSliderActive .line2{display:none}.docsSliderActive .line3{position:absolute;top:50%;transform:rotate(45deg)}.toggleNav h2 i{padding:0 4px}.toc .toggleNav .navGroup{margin-bottom:16px}.toc .toggleNav .subNavGroup{margin-bottom:0}.toc .toggleNav .navGroup .navGroupCategoryTitle{color:#393939;font-size:18px;font-weight:500;line-height:1.2em;margin-bottom:8px;margin-top:0}.toc .toggleNav .navGroup .navGroupSubcategoryTitle{color:#393939;font-size:14px;font-weight:500;line-height:1.5;margin-bottom:0;margin-top:0;padding:4px 0}.toc .toggleNav .navGroup .navListItem{margin:0}.toc .toggleNav .navGroup h3 i:not(:empty){box-sizing:border-box;color:rgba(57,57,57,.5);display:inline-block;height:16px;margin-right:10px;text-align:center;transition:color .2s;width:16px}.toc .toggleNav ul{padding:0 8px}.docsSliderActive .toc .toggleNav ul{padding-left:0}.toc .toggleNav ul li{list-style-type:none;padding:0}.toc .toggleNav ul li a{border:none;color:#717171;display:block;font-size:14px;padding:4px 0;transition:color .3s}.toc .toggleNav ul li.navListItemActive a,.toc .toggleNav ul li a:focus,.toc .toggleNav ul li a:hover{color:#2f1666}.docsSliderActive .toc .navBreadcrumb,.tocActive .navBreadcrumb{border-bottom:1px solid #ccc;margin-bottom:20px;position:fixed;width:100%}.toc .toggleNav .navBreadcrumb h2{border:0;flex-grow:1;font-size:16px;font-weight:600;line-height:32px;margin:0;padding:0}.docsSliderActive .toc section .navGroups{display:block;padding-top:60px}.tocToggler{cursor:pointer;height:32px;line-height:32px;margin-right:-10px;padding:0 10px}.icon-toc{box-sizing:border-box;display:inline-block;line-height:normal;position:relative;top:-1px;vertical-align:middle}.icon-toc,.icon-toc:after,.icon-toc:before{background-color:currentColor;border:1px solid;border-radius:50%;box-sizing:border-box;height:4px;width:4px}.icon-toc:after,.icon-toc:before{content:\"\";position:absolute}.icon-toc:before{left:-1px;top:-7px}.icon-toc:after{left:-1px;top:5px}.tocActive .icon-toc{border-radius:0;height:16px;transform:rotate(45deg);width:3px}.tocActive .icon-toc:before{border-radius:0;height:3px;left:50%;top:50%;transform:translate(-50%,-50%);width:16px}.tocActive .icon-toc:after{content:\"\"}@media only screen and (min-width:1024px){.docMainWrapper{display:flex;flex-flow:row nowrap}.docMainWrapper .wrapper{padding-top:0;padding-left:0;padding-right:0}}.onPageNav{display:none;margin-bottom:40px}.onPageNav::-webkit-scrollbar{width:7px}.onPageNav::-webkit-scrollbar-track{background:#f1f1f1;border-radius:10px}.onPageNav::-webkit-scrollbar-thumb{background:#888;border-radius:10px}.onPageNav::-webkit-scrollbar-thumb:hover{background:#555}.onPageNav a{color:#717171}.onPageNav .toc-headings>li>a.active,.onPageNav .toc-headings>li>a.hover{font-weight:600;color:#2f1666}.onPageNav ul{list-style:none}.onPageNav ul li{font-size:12px;line-height:16px;padding-bottom:8px}.onPageNav ul ul{padding:8px 0 0 20px}.onPageNav ul ul li{padding-bottom:5px}@media only screen and (min-width:1024px){.toc section .navGroups{display:block;padding:8px 0 0}.navBreadcrumb h2{padding:0 10px}}@supports (position:sticky){@media only screen and (max-width:1023px){.tocActive .onPageNav{background:#fff;bottom:0;display:block;left:0;overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:contain;padding:0 20px;position:fixed;right:0;top:148px;z-index:10;margin-bottom:0}.tocActive .singleRowMobileNav .onPageNav{top:98px}.tocActive .navBreadcrumb h2,.tocActive .navToggle{visibility:hidden}.tocActive .onPageNav>.toc-headings{padding:12px 0}}@media only screen and (min-width:1024px){.separateOnPageNav .headerWrapper.wrapper,.separateOnPageNav .wrapper{max-width:1400px}.separateOnPageNav .toc{width:auto}.separateOnPageNav.sideNavVisible .navPusher .mainContainer{flex:1 auto;max-width:100%;min-width:0}.onPageNav{align-self:flex-start;display:block;flex:0 0 240px;max-height:calc(100vh - 90px);overflow-y:auto;position:sticky;top:90px}.onPageNav>.toc-headings{border-left:1px solid #e0e0e0;padding:10px 0 2px 15px}.tocToggler{display:none}}}.blog .wrapper{max-width:1100px}.blogContainer .posts .post{border-bottom:1px solid #e0e0e0;border-radius:3px;margin-bottom:20px;padding-bottom:20px}.blogContainer .postHeader{margin-bottom:10px}.blogContainer .postHeaderTitle{margin-top:0}.blogContainer .postHeader p.post-meta{margin-bottom:10px;padding:0}.blogContainer .postHeader .authorBlock{display:flex}.blogContainer .postHeader .post-authorName{color:rgba(57,57,57,.7);display:flex;flex-direction:column;font-size:14px;font-weight:400;justify-content:center;margin-right:10px;margin-top:0;margin-bottom:0;padding:0}.blogContainer .postHeader .authorPhoto{border-radius:50%;height:30px;overflow:hidden;width:30px}.blogContainer .postHeader .authorPhoto.authorPhotoBig{height:50px;width:50px}.blog-recent{margin:20px 0}.blog-recent>a{float:left}@media only screen and (max-width:735px){.blog-recent{height:40px}}.blogSocialSection{display:block;padding:36px 0}.blogSocialSection .blogSocialSectionItem{padding-bottom:5px}.fb-like{display:block;margin-bottom:20px;width:100%}.more-users{margin:0 auto;max-width:560px;text-align:center}.productShowcaseSection{padding:0 20px;text-align:center}.productShowcaseSection.paddingTop{padding-top:20px}.productShowcaseSection.paddingBottom{padding-bottom:80px}.productShowcaseSection h2{color:#2f1666;font-size:30px;line-height:1em;margin-top:20px;padding:10px 0;text-align:center}.productShowcaseSection p{margin:0 auto;max-width:560px;padding:.8em 0}.productShowcaseSection .logos{align-items:center;display:flex;flex-flow:row wrap;justify-content:center;padding:20px}.productShowcaseSection .logos img{max-height:110px;padding:20px;width:110px}@media only screen and (max-width:735px){.productShowcaseSection .logos img{max-height:64px;padding:20px;width:64px}}.showcaseSection{margin:0 auto;max-width:900px}.showcaseSection,.showcaseSection .prose h1{text-align:center}.showcaseSection .prose{margin:0 auto;max-width:560px;text-align:center}.showcaseSection .logos{align-items:center;display:flex;flex-flow:row wrap;justify-content:center}.showcaseSection .logos img{max-height:128px;padding:20px;width:128px}@media only screen and (max-width:735px){.showcaseSection .logos img{max-height:64px;padding:20px;width:64px}}.nav-footer{background:#20232a;border:none;color:#202020;font-size:15px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;line-height:24px;padding-bottom:2em;padding-top:2em;position:relative}@media only screen and (min-width:1024px){.nav-footer{flex-shrink:0}}.nav-footer .sitemap{display:flex;justify-content:space-between;margin:0 auto 3em;max-width:1080px}.nav-footer .sitemap div{flex:1}.nav-footer .sitemap .nav-home{display:table;height:72px;margin:-12px 20px 0 0;opacity:.4;padding:10px;transition:opacity .15s ease-in-out;width:72px}.nav-footer .sitemap .nav-home:focus,.nav-footer .sitemap .nav-home:hover{opacity:1}@media only screen and (max-width:735px){.nav-footer .sitemap{display:flex;flex-direction:column;margin:0 2em 3em;width:calc(100% - 4em)}.nav-footer .sitemap>div{margin-bottom:18px}}.nav-footer .sitemap a{color:hsla(0,0%,100%,.6);display:block;margin:2px 0;padding:3px 0}.nav-footer .sitemap a:focus,.nav-footer .sitemap a:hover,.nav-footer .sitemap h5>a:focus,.nav-footer .sitemap h5>a:hover{color:#fff;text-decoration:none}.nav-footer .sitemap h5,.nav-footer .sitemap h6{margin:0 0 10px}.nav-footer .sitemap h5,.nav-footer .sitemap h5>a,.nav-footer .sitemap h6,.nav-footer .sitemap h6>a{color:#fff}.nav-footer .sitemap h5>a,.nav-footer .sitemap h6>a{margin:0 -10px}.nav-footer .fbOpenSource{display:block;margin:1em auto;opacity:.4;transition:opacity .15s ease-in-out;width:170px}.nav-footer .fbOpenSource:hover{opacity:1}.nav-footer .copyright{color:hsla(0,0%,100%,.4);text-align:center}.nav-footer .social{padding:5px 0}.tabs{border-top:1px solid #cfcfcf}.nav-tabs{display:flex;border-bottom:4px solid #e0e0e0;width:100%;padding:0;overflow-x:auto;white-space:nowrap;max-height:100%}.nav-tabs::-webkit-scrollbar{display:none}.tabs .tab-pane:focus{outline:none}.tabs .nav-tabs>div{font-size:14px;line-height:1.14286;padding:12px 16px;text-decoration:none;display:block;cursor:pointer}.tabs .nav-tabs>div.active{border-bottom:4px solid #2f1666}.tab-pane{display:none}.tab-pane.active{display:block}.tab-pane>pre{white-space:pre-wrap}.tab-pane>pre>code{margin-top:0;border-radius:0;box-shadow:none}.nav-footer{background-color:#2f1666}.nav-home.custom{height:auto!important;width:auto!important;padding:0 10px!important}"
  },
  {
    "path": "website/build/Kakunin/css/prism.css",
    "content": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * Modified prism.js default theme for JavaScript, CSS and HTML\n * Based on dabblet (http://dabblet.com)\n * @author Lea Verou\n */\n\ncode[class*='language-'],\npre[class*='language-'] {\n  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n  text-align: left;\n  white-space: pre;\n  word-spacing: normal;\n  word-break: normal;\n  word-wrap: normal;\n  line-height: 1.5;\n\n  -moz-tab-size: 4;\n  -o-tab-size: 4;\n  tab-size: 4;\n\n  -webkit-hyphens: none;\n  -moz-hyphens: none;\n  -ms-hyphens: none;\n  hyphens: none;\n}\n\n/* Code blocks */\npre[class*='language-'] {\n  padding: 1em;\n  margin: 0.5em 0;\n  overflow: auto;\n}\n\n/* Inline code */\n:not(pre) > code[class*='language-'] {\n  padding: 0.1em;\n  border-radius: 0.3em;\n  white-space: normal;\n}\n\n.token.comment,\n.token.prolog,\n.token.doctype,\n.token.cdata {\n  color: slategray;\n}\n\n.token.punctuation {\n  color: #999;\n}\n\n.namespace {\n  opacity: 0.7;\n}\n\n.token.property,\n.token.tag,\n.token.boolean,\n.token.constant,\n.token.symbol,\n.token.deleted {\n  color: #905;\n}\n\n.token.selector,\n.token.number,\n.token.attr-name,\n.token.string,\n.token.char,\n.token.builtin,\n.token.inserted {\n  color: #690;\n}\n\n.token.operator,\n.token.entity,\n.token.url,\n.language-css .token.string,\n.style .token.string {\n  color: #9a6e3a;\n}\n\n.token.atrule,\n.token.attr-value,\n.token.keyword {\n  color: #07a;\n}\n\n.token.function,\n.token.class-name {\n  color: #dd4a68;\n}\n\n.token.regex,\n.token.important,\n.token.variable {\n  color: #e90;\n}\n\n.token.important,\n.token.bold {\n  font-weight: bold;\n}\n.token.italic {\n  font-style: italic;\n}\n\n.token.entity {\n  cursor: help;\n}\n"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/configuration/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Configuration · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## Kakunin config\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Configuration · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## Kakunin config\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Configuration</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"kakunin-config\"></a><a href=\"#kakunin-config\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Kakunin config</h2>\n<pre><code class=\"hljs\">module.exports = {\n    <span class=\"hljs-string\">\"browserWidth\"</span>: <span class=\"hljs-number\">1600</span>,\n    <span class=\"hljs-string\">\"browserHeight\"</span>: <span class=\"hljs-number\">900</span>,\n    <span class=\"hljs-string\">\"timeout\"</span>: <span class=\"hljs-number\">60</span>,\n    <span class=\"hljs-string\">\"maxEmailRepeats\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"intervalEmail\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"elementsVisibilityTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"waitForPageTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"downloadTimeout\"</span>: <span class=\"hljs-number\">30</span>,\n    <span class=\"hljs-string\">\"reports\"</span>: <span class=\"hljs-string\">\"/reports\"</span>,\n    <span class=\"hljs-string\">\"downloads\"</span>: <span class=\"hljs-string\">\"/downloads\"</span>,\n    <span class=\"hljs-string\">\"data\"</span>: <span class=\"hljs-string\">\"/data\"</span>,\n    <span class=\"hljs-string\">\"features\"</span>: [\n        <span class=\"hljs-string\">\"/features\"</span>\n    ],\n    <span class=\"hljs-string\">\"pages\"</span>: [\n        <span class=\"hljs-string\">\"/pages\"</span>\n    ],\n    <span class=\"hljs-string\">\"matchers\"</span>: [\n        <span class=\"hljs-string\">\"/matchers\"</span>\n    ],\n    <span class=\"hljs-string\">\"generators\"</span>: [\n        <span class=\"hljs-string\">\"/generators\"</span>\n    ],\n    <span class=\"hljs-string\">\"form_handlers\"</span>: [\n        <span class=\"hljs-string\">\"/form_handlers\"</span>\n    ],\n    <span class=\"hljs-string\">\"step_definitions\"</span>: [\n        <span class=\"hljs-string\">\"/step_definitions\"</span>\n    ],\n    <span class=\"hljs-string\">\"comparators\"</span>: [\n        <span class=\"hljs-string\">\"/comparators\"</span>\n    ],\n    <span class=\"hljs-string\">\"dictionaries\"</span>: [\n        <span class=\"hljs-string\">\"/dictionaries\"</span>\n    ],\n    <span class=\"hljs-string\">\"transformers\"</span>: [\n        <span class=\"hljs-string\">\"/transformers\"</span>\n    ],\n    <span class=\"hljs-string\">\"regexes\"</span>: [\n        <span class=\"hljs-string\">\"/regexes\"</span>\n    ],\n    <span class=\"hljs-string\">\"hooks\"</span>: [\n        <span class=\"hljs-string\">\"/hooks\"</span>\n    ],\n    <span class=\"hljs-string\">\"clearEmailInboxBeforeTests\"</span>: false,\n    <span class=\"hljs-string\">\"clearCookiesAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"clearLocalStorageAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"email\"</span>: null,\n    <span class=\"hljs-string\">\"headless\"</span>: false,\n    <span class=\"hljs-string\">\"noGpu\"</span>: false,\n    <span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"otherWeb\"</span>,\n    <span class=\"hljs-string\">\"baseUrl\"</span>: <span class=\"hljs-string\">\"http://localhost:8080\"</span>,\n    <span class=\"hljs-string\">\"accounts\"</span>: {\n        <span class=\"hljs-string\">\"someAccount\"</span>: {\n            <span class=\"hljs-string\">\"accounts\"</span>: [\n                {\n                    <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n                    <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n                }\n            ]\n        }\n    }\n}\n\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration-options\"></a><a href=\"#configuration-options\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration options</h2>\n<p><code>browserWidth</code> - width of browser window <code>default: 1600</code></p>\n<p><code>browserheight</code> - height of browser window <code>default: 900</code></p>\n<p><code>timeout</code> - global timeout for a single step execution in seconds <code>default: 60</code></p>\n<p><code>maxEmailRepeats</code> - maximum email repeats to catch email used in the email step</p>\n<p><code>intervalEmail</code> - interval for email checking step <code>default: 5</code> in seconds</p>\n<p><code>elementsVisibilityTimeout</code> - maximum wait timeout for element visibility <code>default: 5</code> seconds</p>\n<p><code>waitForPageTimeout</code> - maximum wait timeout for page visibility <code>default: 5</code> seconds</p>\n<p><code>downloadTimeout</code> - maximum wait timeout for file to be downloaded <code>default: 30</code> seconds</p>\n<p><code>emails</code> - array of paths to store emails related custom code</p>\n<p><code>reports</code> - path to store reports</p>\n<p><code>downloads</code> - path to store downloaded files</p>\n<p><code>data</code> - path to store test related files (for example files to be downloaded)</p>\n<p><code>feature</code> - array of paths to store features</p>\n<p><code>pages</code> - array of paths to store page objects</p>\n<p><code>matchers</code> - array of paths to store custom matchers</p>\n<p><code>generators</code> - array of paths to store custom generators</p>\n<p><code>form_handlers</code> - array of paths to store custom form handlers</p>\n<p><code>step_definitions</code> - array of paths to store custom steps</p>\n<p><code>comparators</code> - array of paths to store custom comparators</p>\n<p><code>dictionaries</code> - array of paths to store custom dictionaries</p>\n<p><code>transformers</code> - array of paths to store custom transformers</p>\n<p><code>regexes</code> - array of paths to store custom regexes</p>\n<p><code>hooks</code> - array of paths to store custom hooks</p>\n<p><code>clearEmailInboxBeforeTests</code> - flag to active clearing email inbox before tests are executed <code>default: false | true for apps with email checking functionality activated</code></p>\n<p><code>clearCookiesAfterScenario</code> - flag to activate clearing cookies after every scenario <code>default: true</code></p>\n<p><code>clearLocalStorageAfterScenario</code> - flag to activate clearing local storage after every scenario <code>default: true</code></p>\n<p><code>email</code> - email configuration <code>default: null</code></p>\n<p>for mailtrap email checking system:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"mailtrap\"</span>,\n<span class=\"hljs-string\">\"config\"</span>: {\n    <span class=\"hljs-string\">\"apiKey\"</span>: <span class=\"hljs-string\">\"your-mailtrap-api-key\"</span>,\n    <span class=\"hljs-string\">\"inboxId\"</span>: <span class=\"hljs-string\">\"your-mailtrap-inbox\"</span>,\n    <span class=\"hljs-string\">\"url\"</span>: <span class=\"hljs-string\">\"https://mailtrap.io/api/v1\"</span>\n}\n</code></pre>\n<p>for custom email checking system only type is required:</p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"custom-type\"</span>\n</code></pre>\n<p><code>headless</code> - flag to activate chrome headless browser <code>default: false</code></p>\n<p><code>noGpu</code> - flag to activate cpu only mode <code>default: false</code></p>\n<p><code>type</code> - type of application either <code>ng1 | ng2 | otherWeb</code></p>\n<p><code>baseUrl</code> - url of tested application</p>\n<p><code>accounts</code> - object to store accounts information. This is bound to <code>userProvider</code> and allows to use advanced email checking options like recipient checking.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"someAccount\"</span>: {\n    <span class=\"hljs-string\">\"accounts\"</span>: [\n        {\n            <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n            <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n        }\n    ]\n}\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"environment-variables\"></a><a href=\"#environment-variables\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Environment variables</h2>\n<p>Kakunin uses a single <code>.env</code> file to load ENV variables. By default there is only one:</p>\n<p><code>FIXTURES_RELOAD_HOST</code> - allows you to specify host for fixtures reloading. This allows you to use <code>@reloadFixtures</code> tag on scenarios that should restore database to starting state, before the test is running</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/index\"><span class=\"arrow-prev\">← </span><span>Getting started</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/how-it-works\"><span>How it works</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#kakunin-config\">Kakunin config</a></li><li><a href=\"#configuration-options\">Configuration options</a></li><li><a href=\"#environment-variables\">Environment variables</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/configuration.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Configuration · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## Kakunin config\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Configuration · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## Kakunin config\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Configuration</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"kakunin-config\"></a><a href=\"#kakunin-config\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Kakunin config</h2>\n<pre><code class=\"hljs\">module.exports = {\n    <span class=\"hljs-string\">\"browserWidth\"</span>: <span class=\"hljs-number\">1600</span>,\n    <span class=\"hljs-string\">\"browserHeight\"</span>: <span class=\"hljs-number\">900</span>,\n    <span class=\"hljs-string\">\"timeout\"</span>: <span class=\"hljs-number\">60</span>,\n    <span class=\"hljs-string\">\"maxEmailRepeats\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"intervalEmail\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"elementsVisibilityTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"waitForPageTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"downloadTimeout\"</span>: <span class=\"hljs-number\">30</span>,\n    <span class=\"hljs-string\">\"reports\"</span>: <span class=\"hljs-string\">\"/reports\"</span>,\n    <span class=\"hljs-string\">\"downloads\"</span>: <span class=\"hljs-string\">\"/downloads\"</span>,\n    <span class=\"hljs-string\">\"data\"</span>: <span class=\"hljs-string\">\"/data\"</span>,\n    <span class=\"hljs-string\">\"features\"</span>: [\n        <span class=\"hljs-string\">\"/features\"</span>\n    ],\n    <span class=\"hljs-string\">\"pages\"</span>: [\n        <span class=\"hljs-string\">\"/pages\"</span>\n    ],\n    <span class=\"hljs-string\">\"matchers\"</span>: [\n        <span class=\"hljs-string\">\"/matchers\"</span>\n    ],\n    <span class=\"hljs-string\">\"generators\"</span>: [\n        <span class=\"hljs-string\">\"/generators\"</span>\n    ],\n    <span class=\"hljs-string\">\"form_handlers\"</span>: [\n        <span class=\"hljs-string\">\"/form_handlers\"</span>\n    ],\n    <span class=\"hljs-string\">\"step_definitions\"</span>: [\n        <span class=\"hljs-string\">\"/step_definitions\"</span>\n    ],\n    <span class=\"hljs-string\">\"comparators\"</span>: [\n        <span class=\"hljs-string\">\"/comparators\"</span>\n    ],\n    <span class=\"hljs-string\">\"dictionaries\"</span>: [\n        <span class=\"hljs-string\">\"/dictionaries\"</span>\n    ],\n    <span class=\"hljs-string\">\"transformers\"</span>: [\n        <span class=\"hljs-string\">\"/transformers\"</span>\n    ],\n    <span class=\"hljs-string\">\"regexes\"</span>: [\n        <span class=\"hljs-string\">\"/regexes\"</span>\n    ],\n    <span class=\"hljs-string\">\"hooks\"</span>: [\n        <span class=\"hljs-string\">\"/hooks\"</span>\n    ],\n    <span class=\"hljs-string\">\"clearEmailInboxBeforeTests\"</span>: false,\n    <span class=\"hljs-string\">\"clearCookiesAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"clearLocalStorageAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"email\"</span>: null,\n    <span class=\"hljs-string\">\"headless\"</span>: false,\n    <span class=\"hljs-string\">\"noGpu\"</span>: false,\n    <span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"otherWeb\"</span>,\n    <span class=\"hljs-string\">\"baseUrl\"</span>: <span class=\"hljs-string\">\"http://localhost:8080\"</span>,\n    <span class=\"hljs-string\">\"accounts\"</span>: {\n        <span class=\"hljs-string\">\"someAccount\"</span>: {\n            <span class=\"hljs-string\">\"accounts\"</span>: [\n                {\n                    <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n                    <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n                }\n            ]\n        }\n    }\n}\n\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration-options\"></a><a href=\"#configuration-options\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration options</h2>\n<p><code>browserWidth</code> - width of browser window <code>default: 1600</code></p>\n<p><code>browserheight</code> - height of browser window <code>default: 900</code></p>\n<p><code>timeout</code> - global timeout for a single step execution in seconds <code>default: 60</code></p>\n<p><code>maxEmailRepeats</code> - maximum email repeats to catch email used in the email step</p>\n<p><code>intervalEmail</code> - interval for email checking step <code>default: 5</code> in seconds</p>\n<p><code>elementsVisibilityTimeout</code> - maximum wait timeout for element visibility <code>default: 5</code> seconds</p>\n<p><code>waitForPageTimeout</code> - maximum wait timeout for page visibility <code>default: 5</code> seconds</p>\n<p><code>downloadTimeout</code> - maximum wait timeout for file to be downloaded <code>default: 30</code> seconds</p>\n<p><code>emails</code> - array of paths to store emails related custom code</p>\n<p><code>reports</code> - path to store reports</p>\n<p><code>downloads</code> - path to store downloaded files</p>\n<p><code>data</code> - path to store test related files (for example files to be downloaded)</p>\n<p><code>feature</code> - array of paths to store features</p>\n<p><code>pages</code> - array of paths to store page objects</p>\n<p><code>matchers</code> - array of paths to store custom matchers</p>\n<p><code>generators</code> - array of paths to store custom generators</p>\n<p><code>form_handlers</code> - array of paths to store custom form handlers</p>\n<p><code>step_definitions</code> - array of paths to store custom steps</p>\n<p><code>comparators</code> - array of paths to store custom comparators</p>\n<p><code>dictionaries</code> - array of paths to store custom dictionaries</p>\n<p><code>transformers</code> - array of paths to store custom transformers</p>\n<p><code>regexes</code> - array of paths to store custom regexes</p>\n<p><code>hooks</code> - array of paths to store custom hooks</p>\n<p><code>clearEmailInboxBeforeTests</code> - flag to active clearing email inbox before tests are executed <code>default: false | true for apps with email checking functionality activated</code></p>\n<p><code>clearCookiesAfterScenario</code> - flag to activate clearing cookies after every scenario <code>default: true</code></p>\n<p><code>clearLocalStorageAfterScenario</code> - flag to activate clearing local storage after every scenario <code>default: true</code></p>\n<p><code>email</code> - email configuration <code>default: null</code></p>\n<p>for mailtrap email checking system:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"mailtrap\"</span>,\n<span class=\"hljs-string\">\"config\"</span>: {\n    <span class=\"hljs-string\">\"apiKey\"</span>: <span class=\"hljs-string\">\"your-mailtrap-api-key\"</span>,\n    <span class=\"hljs-string\">\"inboxId\"</span>: <span class=\"hljs-string\">\"your-mailtrap-inbox\"</span>,\n    <span class=\"hljs-string\">\"url\"</span>: <span class=\"hljs-string\">\"https://mailtrap.io/api/v1\"</span>\n}\n</code></pre>\n<p>for custom email checking system only type is required:</p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"custom-type\"</span>\n</code></pre>\n<p><code>headless</code> - flag to activate chrome headless browser <code>default: false</code></p>\n<p><code>noGpu</code> - flag to activate cpu only mode <code>default: false</code></p>\n<p><code>type</code> - type of application either <code>ng1 | ng2 | otherWeb</code></p>\n<p><code>baseUrl</code> - url of tested application</p>\n<p><code>accounts</code> - object to store accounts information. This is bound to <code>userProvider</code> and allows to use advanced email checking options like recipient checking.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"someAccount\"</span>: {\n    <span class=\"hljs-string\">\"accounts\"</span>: [\n        {\n            <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n            <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n        }\n    ]\n}\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"environment-variables\"></a><a href=\"#environment-variables\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Environment variables</h2>\n<p>Kakunin uses a single <code>.env</code> file to load ENV variables. By default there is only one:</p>\n<p><code>FIXTURES_RELOAD_HOST</code> - allows you to specify host for fixtures reloading. This allows you to use <code>@reloadFixtures</code> tag on scenarios that should restore database to starting state, before the test is running</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/index\"><span class=\"arrow-prev\">← </span><span>Getting started</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/how-it-works\"><span>How it works</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#kakunin-config\">Kakunin config</a></li><li><a href=\"#configuration-options\">Configuration options</a></li><li><a href=\"#environment-variables\">Environment variables</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/cross-browser/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Cross-browser testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## To run tests with specified browser\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Cross-browser testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## To run tests with specified browser\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Cross-browser testing</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-with-specified-browser\"></a><a href=\"#to-run-tests-with-specified-browser\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests with specified browser</h2>\n<p>There is a possibility to run Kakunin in various browsers:</p>\n<ul>\n<li>Google Chrome (by default) <code>npm run kakunin</code> or <code>npm run kakunin -- --chrome</code></li>\n<li>Firefox <code>npm run kakunin -- --firefox</code></li>\n<li>Safari <code>npm run kakunin -- --safari</code></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-in-different-browsers-at-once\"></a><a href=\"#to-run-tests-in-different-browsers-at-once\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests in different browsers at once</h2>\n<p>There is a possibility to run more than one instance of WebDriver by giving an extra parameter to a command line:</p>\n<ul>\n<li><code>npm run kakunin --chrome --firefox</code></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"safari\"></a><a href=\"#safari\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Safari</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h3>\n<ol>\n<li>Open Safari's preferences</li>\n<li>Enable &quot;Show Develop menu in menu bar&quot;</li>\n<li>Open &quot;Develop&quot; tab</li>\n<li>Enable &quot;Allow Remote Automation&quot;</li>\n</ol>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h3>\n<p>Safari version 12.0:</p>\n<ul>\n<li>drag &amp; drop actions in Kakunin impossible (more details <a href=\"https://github.com/angular/protractor/issues/1526\">https://github.com/angular/protractor/issues/1526</a>)</li>\n</ul>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/extending\"><span class=\"arrow-prev\">← </span><span>Extending Kakunin</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/parallel-testing\"><span>Parallel testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#to-run-tests-with-specified-browser\">To run tests with specified browser</a></li><li><a href=\"#to-run-tests-in-different-browsers-at-once\">To run tests in different browsers at once</a></li><li><a href=\"#safari\">Safari</a><ul class=\"toc-headings\"><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/cross-browser.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Cross-browser testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## To run tests with specified browser\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Cross-browser testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## To run tests with specified browser\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Cross-browser testing</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-with-specified-browser\"></a><a href=\"#to-run-tests-with-specified-browser\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests with specified browser</h2>\n<p>There is a possibility to run Kakunin in various browsers:</p>\n<ul>\n<li>Google Chrome (by default) <code>npm run kakunin</code> or <code>npm run kakunin -- --chrome</code></li>\n<li>Firefox <code>npm run kakunin -- --firefox</code></li>\n<li>Safari <code>npm run kakunin -- --safari</code></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-in-different-browsers-at-once\"></a><a href=\"#to-run-tests-in-different-browsers-at-once\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests in different browsers at once</h2>\n<p>There is a possibility to run more than one instance of WebDriver by giving an extra parameter to a command line:</p>\n<ul>\n<li><code>npm run kakunin --chrome --firefox</code></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"safari\"></a><a href=\"#safari\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Safari</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h3>\n<ol>\n<li>Open Safari's preferences</li>\n<li>Enable &quot;Show Develop menu in menu bar&quot;</li>\n<li>Open &quot;Develop&quot; tab</li>\n<li>Enable &quot;Allow Remote Automation&quot;</li>\n</ol>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h3>\n<p>Safari version 12.0:</p>\n<ul>\n<li>drag &amp; drop actions in Kakunin impossible (more details <a href=\"https://github.com/angular/protractor/issues/1526\">https://github.com/angular/protractor/issues/1526</a>)</li>\n</ul>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/extending\"><span class=\"arrow-prev\">← </span><span>Extending Kakunin</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/parallel-testing\"><span>Parallel testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#to-run-tests-with-specified-browser\">To run tests with specified browser</a></li><li><a href=\"#to-run-tests-in-different-browsers-at-once\">To run tests in different browsers at once</a></li><li><a href=\"#safari\">Safari</a><ul class=\"toc-headings\"><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/docker/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Docker · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Docker for Kakunin tests\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Docker · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Docker for Kakunin tests\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Docker</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"docker-for-kakunin-tests\"></a><a href=\"#docker-for-kakunin-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Docker for Kakunin tests</h1>\n<p>This section explains how to run kakunin tests inside docker, below examples of Dockerfile\nand docker-compose.yml files let you build your first docker image and run tests.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dockerfile\"></a><a href=\"#dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dockerfile:</h2>\n<p>This file is responsible for building the whole environment for our e2e tests.\nIt will allow you to run tests on local and CI environments,\nby configuring and copying the whole project inside the container.\nJust simply place it inside your e2e project root.</p>\n<p>Below an example of Dockerfile</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-dockerfile\"></a><a href=\"#example-of-dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of Dockerfile:</h3>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-comment\"># Downloading selenium image and setting privileges</span>\nFROM selenium/standalone-chrome:3.14.0\nUSER root\n<span class=\"hljs-comment\"># Setting test directory</span>\nWORKDIR /app\n<span class=\"hljs-comment\"># Install openjdk-8-jdk-headless</span>\nRUN apt-get update -qqy \\\n  &amp;&amp; apt-get -qqy --no-install-recommends install \\\n    xvfb \\\n    openjdk-8-jdk-headless \\\n    curl \\\n    make \\\n  &amp;&amp; rm -rf /var/lib/apt/lists/* /var/cache/apt/*\n<span class=\"hljs-comment\"># Installing node 8 globally and setting paths</span>\nRUN <span class=\"hljs-built_in\">set</span> -x \\\n    &amp;&amp; curl -sL https://deb.nodesource.com/setup_8.x | bash - \\\n    &amp;&amp; apt-get install -y \\\n        nodejs \\\n    &amp;&amp; npm install -g npm@latest\nRUN PATH=/usr/bin/node:<span class=\"hljs-variable\">$PATH</span>\n<span class=\"hljs-comment\"># Copy tests directory with ignored files from .dockerignore</span>\nCOPY --chown=seluser:seluser . .\n<span class=\"hljs-comment\"># Removing node_modules in case of existence or lack of .dockerignore and installing from package.json</span>\nRUN rm -rf ./node_modules \\\n    &amp;&amp; npm install\n<span class=\"hljs-comment\"># Setting Xvfb</span>\nRUN <span class=\"hljs-built_in\">export</span> DISPLAY=:99.0\nUSER seluser\n</code></pre>\n<p>##docker-compose.yml</p>\n<p>Compose is a tool for defining and running multi-container Docker applications, which we use\nfor running our tests.</p>\n<p>Running command: <code>docker-compose up -d</code> will start Dockerfile script, as a result, it builds the container.</p>\n<p>Running command: <code>docker-compose build</code> or <code>docker-compose up --build</code> will\nrebuild container, if there were made any changes.</p>\n<p>Running command: <code>docker-compose run --rm e2e</code> will start running tests inside the container</p>\n<p>Composition below allows you to run e2e tests inside the container and configure it locally or\nin CI environments.</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-docker-composeyml\"></a><a href=\"#example-of-docker-composeyml\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of docker-compose.yml:</h3>\n<pre><code class=\"hljs css language-bash\">e2e:\n      build: .\n      working_dir: /app\n      <span class=\"hljs-built_in\">command</span>: sh -c <span class=\"hljs-string\">\"Xvfb -ac :99 -screen 0 1280x1024x16 &amp; npm run kakunin\"</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-run-step-by-step\"></a><a href=\"#how-to-run-step-by-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to run step by step</h3>\n<ol>\n<li>Install docker (e.g Docker for Mac),</li>\n<li>Create Dockerfile and docker-compose.yml in the root of your e2e project,</li>\n<li>Run in command line <code>docker-compose up -d</code> which will start docker and build image\nif it's not build</li>\n<li>Run in command line <code>docker-compose run --rm e2e</code> to run your tests</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/performance-testing\"><span class=\"arrow-prev\">← </span><span>Performance testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-navigation\"><span>Navigation</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dockerfile\">Dockerfile:</a><ul class=\"toc-headings\"><li><a href=\"#example-of-dockerfile\">Example of Dockerfile:</a></li><li><a href=\"#example-of-docker-composeyml\">Example of docker-compose.yml:</a></li><li><a href=\"#how-to-run-step-by-step\">How to run step by step</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/docker.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Docker · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Docker for Kakunin tests\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Docker · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Docker for Kakunin tests\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Docker</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"docker-for-kakunin-tests\"></a><a href=\"#docker-for-kakunin-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Docker for Kakunin tests</h1>\n<p>This section explains how to run kakunin tests inside docker, below examples of Dockerfile\nand docker-compose.yml files let you build your first docker image and run tests.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dockerfile\"></a><a href=\"#dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dockerfile:</h2>\n<p>This file is responsible for building the whole environment for our e2e tests.\nIt will allow you to run tests on local and CI environments,\nby configuring and copying the whole project inside the container.\nJust simply place it inside your e2e project root.</p>\n<p>Below an example of Dockerfile</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-dockerfile\"></a><a href=\"#example-of-dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of Dockerfile:</h3>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-comment\"># Downloading selenium image and setting privileges</span>\nFROM selenium/standalone-chrome:3.14.0\nUSER root\n<span class=\"hljs-comment\"># Setting test directory</span>\nWORKDIR /app\n<span class=\"hljs-comment\"># Install openjdk-8-jdk-headless</span>\nRUN apt-get update -qqy \\\n  &amp;&amp; apt-get -qqy --no-install-recommends install \\\n    xvfb \\\n    openjdk-8-jdk-headless \\\n    curl \\\n    make \\\n  &amp;&amp; rm -rf /var/lib/apt/lists/* /var/cache/apt/*\n<span class=\"hljs-comment\"># Installing node 8 globally and setting paths</span>\nRUN <span class=\"hljs-built_in\">set</span> -x \\\n    &amp;&amp; curl -sL https://deb.nodesource.com/setup_8.x | bash - \\\n    &amp;&amp; apt-get install -y \\\n        nodejs \\\n    &amp;&amp; npm install -g npm@latest\nRUN PATH=/usr/bin/node:<span class=\"hljs-variable\">$PATH</span>\n<span class=\"hljs-comment\"># Copy tests directory with ignored files from .dockerignore</span>\nCOPY --chown=seluser:seluser . .\n<span class=\"hljs-comment\"># Removing node_modules in case of existence or lack of .dockerignore and installing from package.json</span>\nRUN rm -rf ./node_modules \\\n    &amp;&amp; npm install\n<span class=\"hljs-comment\"># Setting Xvfb</span>\nRUN <span class=\"hljs-built_in\">export</span> DISPLAY=:99.0\nUSER seluser\n</code></pre>\n<p>##docker-compose.yml</p>\n<p>Compose is a tool for defining and running multi-container Docker applications, which we use\nfor running our tests.</p>\n<p>Running command: <code>docker-compose up -d</code> will start Dockerfile script, as a result, it builds the container.</p>\n<p>Running command: <code>docker-compose build</code> or <code>docker-compose up --build</code> will\nrebuild container, if there were made any changes.</p>\n<p>Running command: <code>docker-compose run --rm e2e</code> will start running tests inside the container</p>\n<p>Composition below allows you to run e2e tests inside the container and configure it locally or\nin CI environments.</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-docker-composeyml\"></a><a href=\"#example-of-docker-composeyml\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of docker-compose.yml:</h3>\n<pre><code class=\"hljs css language-bash\">e2e:\n      build: .\n      working_dir: /app\n      <span class=\"hljs-built_in\">command</span>: sh -c <span class=\"hljs-string\">\"Xvfb -ac :99 -screen 0 1280x1024x16 &amp; npm run kakunin\"</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-run-step-by-step\"></a><a href=\"#how-to-run-step-by-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to run step by step</h3>\n<ol>\n<li>Install docker (e.g Docker for Mac),</li>\n<li>Create Dockerfile and docker-compose.yml in the root of your e2e project,</li>\n<li>Run in command line <code>docker-compose up -d</code> which will start docker and build image\nif it's not build</li>\n<li>Run in command line <code>docker-compose run --rm e2e</code> to run your tests</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/performance-testing\"><span class=\"arrow-prev\">← </span><span>Performance testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-navigation\"><span>Navigation</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dockerfile\">Dockerfile:</a><ul class=\"toc-headings\"><li><a href=\"#example-of-dockerfile\">Example of Dockerfile:</a></li><li><a href=\"#example-of-docker-composeyml\">Example of docker-compose.yml:</a></li><li><a href=\"#how-to-run-step-by-step\">How to run step by step</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/extending/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Extending Kakunin · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Extending Kakunin · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Extending Kakunin</h1></header><article><div><span><p>Kakunin allows you to easily add a custom code in order to extend it's functionality.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"internal-services\"></a><a href=\"#internal-services\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Internal services</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-builder\"></a><a href=\"#regex-builder\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex builder</h3>\n<p>Regex builder is a special builder for creating <code>RegExp</code> objects based on regexp name. Internally it has access to not only to all built-in\nregular expression files, but also custom ones specified by user.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { regexBuilder } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> myRegex = regexBuilder.buildRegex(<span class=\"hljs-string\">'r:number'</span>);\n\n<span class=\"hljs-comment\">//myRegex will contain RegExp object that matches regular expression under the name \"number\" in regexes file.</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h3>\n<p>Variable store allows you to store and read some values to be used during given scenario.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { variableStore } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\nvariableStore.storeVariable(<span class=\"hljs-string\">'some-name'</span>, <span class=\"hljs-string\">'some-value'</span>);\n\n<span class=\"hljs-keyword\">const</span> myValue = variableStore.getVariableValue(<span class=\"hljs-string\">'some-name'</span>); <span class=\"hljs-comment\">//contains 'some-value'</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"user-provider\"></a><a href=\"#user-provider\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User provider</h3>\n<p>Kakunin comes with functionality that allows you to easily load credentials for a given account type - <code>UserProvider</code>.</p>\n<p>In <code>kakunin.conf.js</code> you can find a section <code>accounts</code>.</p>\n<p>The structure it has is very simple:</p>\n<pre><code class=\"hljs css language-json\">\"accounts\": {\n    \"someAccount\": {\n        \"accounts\": [\n            {\n                \"email\": \"\",\n                \"password\": \"\"\n            }\n        ]\n    }\n}\n</code></pre>\n<p><code>someAccount</code> - the name of accounts group</p>\n<p><code>accounts</code> - an array of account credentials (in order to be able to check if a <code>currentUser</code> got an email, this has to have an <code>email</code> key, otherwise account can have any kind of\nproperties)</p>\n<p>Use provider is accessible inside any kind of a step by calling <code>this.userProvider</code>. It comes with a single method:</p>\n<p><code>this.userProvider.getUser(groupName)</code> - returns an account credentials for a given user group.</p>\n<p>It is a good practice to save a current user in <code>this.currentUser</code> variable for a email checking service.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"adding-custom-code\"></a><a href=\"#adding-custom-code\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding custom code</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"custom-step\"></a><a href=\"#custom-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Custom step</h3>\n<p>In order to add a custom step, you have to create inside of a directory specified as <code>step_definitions</code> in kakunin configuration file <code>default: /step_definitions</code>.</p>\n<p>We're using <code>cucumber-js 4.X</code> so in order to add custom step you have to use <code>defineSupportCode</code> method like this:</p>\n<pre><code class=\"hljs css language-javascript\">  <span class=\"hljs-keyword\">const</span> { defineSupportCode } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n  \n  defineSupportCode(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ When }</span>) =&gt;</span> {\n    When(<span class=\"hljs-regexp\">/^I use kakunin$/</span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) </span>{\n      expect(<span class=\"hljs-literal\">true</span>).to.equal(<span class=\"hljs-literal\">true</span>);\n    });\n  });\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h3>\n<p>Kakunin comes with some built-in page objects, that should be used as a base for your page objects.</p>\n<p>In order to create a custom one, create a file inside the <code>pages</code> directory and extend the <code>BasePage</code> from kakunin package.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyPageObject</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.myElement = element(by.css(<span class=\"hljs-string\">'.some-elemnt'</span>));\n  }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MyPageObject;\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"matchers\"></a><a href=\"#matchers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Matchers</h3>\n<p>Matchers are used to compare if given value is matching our expectation. For example if a value in table is a number.</p>\n<p>You can add your own matcher as below:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { matchers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyMatcher</span> </span>{\n  isSatisfiedBy(prefix, name) {\n    <span class=\"hljs-keyword\">return</span> prefix === <span class=\"hljs-string\">'m:'</span> &amp;&amp; name === <span class=\"hljs-string\">'pending'</span>;\n  }\n \n  match(protractorElement, matcherName) {\n    <span class=\"hljs-keyword\">return</span> protractorElement.getText().then(<span class=\"hljs-function\">(<span class=\"hljs-params\">value</span>) =&gt;</span> {\n      <span class=\"hljs-keyword\">if</span> (value === <span class=\"hljs-string\">'pending'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n      }\n      \n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Matcher \"MyMatcher\" could not match value on element \"<span class=\"hljs-subst\">${protractorElement.locator()}</span>\". Expected: \"pending\", given: \"<span class=\"hljs-subst\">${value}</span>\"`</span>);\n    }); \n  }\n}\n\nmatchers.addMatcher(<span class=\"hljs-keyword\">new</span> MyMatcher());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h3>\n<p>Dictionaries allows you to present complicated values in much more readable way. For example if an element must be\nin a form of IRI <code>/some-resource/123-123-123-23</code> and you wish to use <code>pending-resource</code> as it's alias.</p>\n<p>You can add your own dictionary:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { dictionaries } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n<span class=\"hljs-keyword\">const</span> { BaseDictionary } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">TestDictionary</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BaseDictionary</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">super</span>(<span class=\"hljs-string\">'name-of-dictionary'</span>, {\n      <span class=\"hljs-string\">'pending-resource'</span>: <span class=\"hljs-string\">'/some-resource/123-123-123-23'</span>,\n      <span class=\"hljs-string\">'test-value'</span>: <span class=\"hljs-string\">'some other value'</span>\n    });\n  }\n}\n\ndictionaries.addDictionary(<span class=\"hljs-keyword\">new</span> TestDictionary());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h3>\n<p>Generators allows you to create random values</p>\n<p>You can add your own generator:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { generators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyGeneerator</span></span>{\n  isSatisfiedBy(name) {\n    <span class=\"hljs-keyword\">return</span> name === <span class=\"hljs-string\">'my-generator'</span>;\n  }\n\n  generate(params) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'some-random-value'</span>);\n  }\n}\n\ngenerators.addGenerator(<span class=\"hljs-keyword\">new</span> MyGeneerator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"comparators\"></a><a href=\"#comparators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Comparators</h3>\n<p>Comparators allows you to check if a set of values has an expected order</p>\n<p>You can add your own comparators:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { comparators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyComparator</span> </span>{\n  isSatisfiedBy(values) {\n    <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">let</span> i=<span class=\"hljs-number\">0</span>; i&lt;values.length; i++) {\n      <span class=\"hljs-keyword\">if</span> (values[i] !== <span class=\"hljs-string\">'foo'</span> &amp;&amp; values[i] !== <span class=\"hljs-string\">'bar'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n  }\n  \n  compare(values, order) {\n    <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">let</span> i = <span class=\"hljs-number\">1</span>; i &lt; values.length; i++) {\n      <span class=\"hljs-keyword\">const</span> previousValue = values[i - <span class=\"hljs-number\">1</span>];\n      <span class=\"hljs-keyword\">const</span> currentValue = values[i];\n\n      <span class=\"hljs-keyword\">if</span> (previousValue === currentValue) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">'Wrong order'</span>);\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'Foo bar!'</span>);\n  }\n};\n\ncomparators.addComparator(<span class=\"hljs-keyword\">new</span> MyComparator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"form-handlers\"></a><a href=\"#form-handlers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Form handlers</h3>\n<p>Form handlers allows you to fill the form inputs and check value of filled fields</p>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { handlers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> MyHandler {\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.registerFieldType = <span class=\"hljs-literal\">false</span>;\n    <span class=\"hljs-keyword\">this</span>.fieldType = <span class=\"hljs-string\">'default'</span>;\n  }\n\n  isSatisfiedBy(element, elementName) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(elementName === <span class=\"hljs-string\">'someElementName'</span>);\n  }\n \n  handleFill(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].clear().then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n          <span class=\"hljs-keyword\">return</span> page[elementName].sendKeys(desiredValue);\n        });\n      }\n    );\n  }\n\n  handleCheck(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].getAttribute(<span class=\"hljs-string\">'value'</span>).then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">value</span>) </span>{\n          <span class=\"hljs-keyword\">if</span> (value === desiredValue) {\n            <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve();\n          }\n\n          <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Expected <span class=\"hljs-subst\">${desiredValue}</span> got <span class=\"hljs-subst\">${value}</span> for text input element <span class=\"hljs-subst\">${elementName}</span>`</span>);\n        });\n      }\n    );\n  }\n};\n\nhandlers.addHandler(<span class=\"hljs-keyword\">new</span> MyHandler());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"transformers\"></a><a href=\"#transformers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Transformers</h3>\n<p>Transformers can be used in steps <code>When I fill the &quot;form&quot; form with:</code> and <code>And the &quot;joinOurStoreForm&quot; form is filled with:</code>.</p>\n<p>Existing transformers:</p>\n<ul>\n<li>generators (prefix: <code>g:</code>)</li>\n<li>dictionaries (prefix: <code>d:</code>)</li>\n<li>variableStore (prefix: <code>v:</code>)\nTransformers can be used in mentioned steps by using specific 'prefix', parameters are sent after <code>:</code> sign.\nExample:\n<code>g:generatorName:param:param</code></li>\n</ul>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { transformers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyTransformer</span> </span>{\n\n  isSatisfiedBy(prefix) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-string\">'yourPrefix:'</span> === prefix;\n  }\n\n  transform(value) {\n    <span class=\"hljs-comment\">//code</span>\n  }\n}\ntransformers.addTransformer(<span class=\"hljs-keyword\">new</span> MyTransformer());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"email-checking-service\"></a><a href=\"#email-checking-service\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Email checking service</h3>\n<p>You can easily check emails with Kakunin. By default we give you MailTrap client implementation, but you can easily add your own client.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { emailService } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyEmailService</span> </span>{\n  <span class=\"hljs-comment\">//you have access to full kakunin config</span>\n  isSatisfiedBy(config) {\n    <span class=\"hljs-keyword\">return</span> config.email.type === <span class=\"hljs-string\">'my-custom-email-service'</span>;\n  }\n  \n  <span class=\"hljs-comment\">//method used to clear emails before tests</span>\n  clearInbox() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to get emails - this method should return emails in format described below</span>\n  getEmails() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to retrive atachments for given email - should return attachments in format described below</span>\n  getAttachments(email) {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to mark given email as read</span>\n  markAsRead(email) {\n    ...\n  }\n}\n\nemailService.addAdapter(<span class=\"hljs-keyword\">new</span> MyEmailService());\n</code></pre>\n<p>Emails should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"subject\"</span>: <span class=\"hljs-string\">\"SMTP e-mail test\"</span>,\n      <span class=\"hljs-string\">\"sent_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.567+03:00\"</span>,\n      <span class=\"hljs-string\">\"from_email\"</span>: <span class=\"hljs-string\">\"me@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"from_name\"</span>: <span class=\"hljs-string\">\"Private Person\"</span>,\n      <span class=\"hljs-string\">\"to_email\"</span>: <span class=\"hljs-string\">\"test@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"to_name\"</span>: <span class=\"hljs-string\">\"A Test User\"</span>,\n      <span class=\"hljs-string\">\"html_body\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"text_body\"</span>: <span class=\"hljs-string\">\"This is a test e-mail message.\\r\\n\"</span>,\n      <span class=\"hljs-string\">\"email_size\"</span>: <span class=\"hljs-number\">193</span>,\n      <span class=\"hljs-string\">\"is_read\"</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.576+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:09.232+03:00\"</span>,\n      <span class=\"hljs-string\">\"sent_at_timestamp\"</span>: <span class=\"hljs-number\">1377448326</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap email format.</p>\n<p>Attachments should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"id\"</span>: <span class=\"hljs-number\">1737</span>,\n      <span class=\"hljs-string\">\"message_id\"</span>: <span class=\"hljs-number\">54508</span>,\n      <span class=\"hljs-string\">\"filename\"</span>: <span class=\"hljs-string\">\"Photos.png\"</span>,\n      <span class=\"hljs-string\">\"attachment_type\"</span>: <span class=\"hljs-string\">\"attachment\"</span>,\n      <span class=\"hljs-string\">\"content_type\"</span>: <span class=\"hljs-string\">\"image/png\"</span>,\n      <span class=\"hljs-string\">\"content_id\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"transfer_encoding\"</span>: <span class=\"hljs-string\">\"base64\"</span>,\n      <span class=\"hljs-string\">\"attachment_size\"</span>: <span class=\"hljs-number\">213855</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"attachment_human_size\"</span>: <span class=\"hljs-string\">\"210 KB\"</span>,\n      <span class=\"hljs-string\">\"download_path\"</span>: <span class=\"hljs-string\">\"/api/v1/inboxes/3/messages/54508/attachments/1737/download\"</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap attachment format.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/transformers\"><span class=\"arrow-prev\">← </span><span>Transformers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/cross-browser\"><span>Cross-browser testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#internal-services\">Internal services</a><ul class=\"toc-headings\"><li><a href=\"#regex-builder\">Regex builder</a></li><li><a href=\"#variable-store\">Variable store</a></li><li><a href=\"#user-provider\">User provider</a></li></ul></li><li><a href=\"#adding-custom-code\">Adding custom code</a><ul class=\"toc-headings\"><li><a href=\"#custom-step\">Custom step</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#matchers\">Matchers</a></li><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#comparators\">Comparators</a></li><li><a href=\"#form-handlers\">Form handlers</a></li><li><a href=\"#transformers\">Transformers</a></li><li><a href=\"#email-checking-service\">Email checking service</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/extending.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Extending Kakunin · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Extending Kakunin · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Extending Kakunin</h1></header><article><div><span><p>Kakunin allows you to easily add a custom code in order to extend it's functionality.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"internal-services\"></a><a href=\"#internal-services\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Internal services</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-builder\"></a><a href=\"#regex-builder\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex builder</h3>\n<p>Regex builder is a special builder for creating <code>RegExp</code> objects based on regexp name. Internally it has access to not only to all built-in\nregular expression files, but also custom ones specified by user.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { regexBuilder } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> myRegex = regexBuilder.buildRegex(<span class=\"hljs-string\">'r:number'</span>);\n\n<span class=\"hljs-comment\">//myRegex will contain RegExp object that matches regular expression under the name \"number\" in regexes file.</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h3>\n<p>Variable store allows you to store and read some values to be used during given scenario.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { variableStore } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\nvariableStore.storeVariable(<span class=\"hljs-string\">'some-name'</span>, <span class=\"hljs-string\">'some-value'</span>);\n\n<span class=\"hljs-keyword\">const</span> myValue = variableStore.getVariableValue(<span class=\"hljs-string\">'some-name'</span>); <span class=\"hljs-comment\">//contains 'some-value'</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"user-provider\"></a><a href=\"#user-provider\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User provider</h3>\n<p>Kakunin comes with functionality that allows you to easily load credentials for a given account type - <code>UserProvider</code>.</p>\n<p>In <code>kakunin.conf.js</code> you can find a section <code>accounts</code>.</p>\n<p>The structure it has is very simple:</p>\n<pre><code class=\"hljs css language-json\">\"accounts\": {\n    \"someAccount\": {\n        \"accounts\": [\n            {\n                \"email\": \"\",\n                \"password\": \"\"\n            }\n        ]\n    }\n}\n</code></pre>\n<p><code>someAccount</code> - the name of accounts group</p>\n<p><code>accounts</code> - an array of account credentials (in order to be able to check if a <code>currentUser</code> got an email, this has to have an <code>email</code> key, otherwise account can have any kind of\nproperties)</p>\n<p>Use provider is accessible inside any kind of a step by calling <code>this.userProvider</code>. It comes with a single method:</p>\n<p><code>this.userProvider.getUser(groupName)</code> - returns an account credentials for a given user group.</p>\n<p>It is a good practice to save a current user in <code>this.currentUser</code> variable for a email checking service.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"adding-custom-code\"></a><a href=\"#adding-custom-code\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding custom code</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"custom-step\"></a><a href=\"#custom-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Custom step</h3>\n<p>In order to add a custom step, you have to create inside of a directory specified as <code>step_definitions</code> in kakunin configuration file <code>default: /step_definitions</code>.</p>\n<p>We're using <code>cucumber-js 4.X</code> so in order to add custom step you have to use <code>defineSupportCode</code> method like this:</p>\n<pre><code class=\"hljs css language-javascript\">  <span class=\"hljs-keyword\">const</span> { defineSupportCode } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n  \n  defineSupportCode(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ When }</span>) =&gt;</span> {\n    When(<span class=\"hljs-regexp\">/^I use kakunin$/</span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) </span>{\n      expect(<span class=\"hljs-literal\">true</span>).to.equal(<span class=\"hljs-literal\">true</span>);\n    });\n  });\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h3>\n<p>Kakunin comes with some built-in page objects, that should be used as a base for your page objects.</p>\n<p>In order to create a custom one, create a file inside the <code>pages</code> directory and extend the <code>BasePage</code> from kakunin package.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyPageObject</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.myElement = element(by.css(<span class=\"hljs-string\">'.some-elemnt'</span>));\n  }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MyPageObject;\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"matchers\"></a><a href=\"#matchers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Matchers</h3>\n<p>Matchers are used to compare if given value is matching our expectation. For example if a value in table is a number.</p>\n<p>You can add your own matcher as below:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { matchers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyMatcher</span> </span>{\n  isSatisfiedBy(prefix, name) {\n    <span class=\"hljs-keyword\">return</span> prefix === <span class=\"hljs-string\">'m:'</span> &amp;&amp; name === <span class=\"hljs-string\">'pending'</span>;\n  }\n \n  match(protractorElement, matcherName) {\n    <span class=\"hljs-keyword\">return</span> protractorElement.getText().then(<span class=\"hljs-function\">(<span class=\"hljs-params\">value</span>) =&gt;</span> {\n      <span class=\"hljs-keyword\">if</span> (value === <span class=\"hljs-string\">'pending'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n      }\n      \n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Matcher \"MyMatcher\" could not match value on element \"<span class=\"hljs-subst\">${protractorElement.locator()}</span>\". Expected: \"pending\", given: \"<span class=\"hljs-subst\">${value}</span>\"`</span>);\n    }); \n  }\n}\n\nmatchers.addMatcher(<span class=\"hljs-keyword\">new</span> MyMatcher());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h3>\n<p>Dictionaries allows you to present complicated values in much more readable way. For example if an element must be\nin a form of IRI <code>/some-resource/123-123-123-23</code> and you wish to use <code>pending-resource</code> as it's alias.</p>\n<p>You can add your own dictionary:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { dictionaries } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n<span class=\"hljs-keyword\">const</span> { BaseDictionary } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">TestDictionary</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BaseDictionary</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">super</span>(<span class=\"hljs-string\">'name-of-dictionary'</span>, {\n      <span class=\"hljs-string\">'pending-resource'</span>: <span class=\"hljs-string\">'/some-resource/123-123-123-23'</span>,\n      <span class=\"hljs-string\">'test-value'</span>: <span class=\"hljs-string\">'some other value'</span>\n    });\n  }\n}\n\ndictionaries.addDictionary(<span class=\"hljs-keyword\">new</span> TestDictionary());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h3>\n<p>Generators allows you to create random values</p>\n<p>You can add your own generator:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { generators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyGeneerator</span></span>{\n  isSatisfiedBy(name) {\n    <span class=\"hljs-keyword\">return</span> name === <span class=\"hljs-string\">'my-generator'</span>;\n  }\n\n  generate(params) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'some-random-value'</span>);\n  }\n}\n\ngenerators.addGenerator(<span class=\"hljs-keyword\">new</span> MyGeneerator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"comparators\"></a><a href=\"#comparators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Comparators</h3>\n<p>Comparators allows you to check if a set of values has an expected order</p>\n<p>You can add your own comparators:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { comparators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyComparator</span> </span>{\n  isSatisfiedBy(values) {\n    <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">let</span> i=<span class=\"hljs-number\">0</span>; i&lt;values.length; i++) {\n      <span class=\"hljs-keyword\">if</span> (values[i] !== <span class=\"hljs-string\">'foo'</span> &amp;&amp; values[i] !== <span class=\"hljs-string\">'bar'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n  }\n  \n  compare(values, order) {\n    <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">let</span> i = <span class=\"hljs-number\">1</span>; i &lt; values.length; i++) {\n      <span class=\"hljs-keyword\">const</span> previousValue = values[i - <span class=\"hljs-number\">1</span>];\n      <span class=\"hljs-keyword\">const</span> currentValue = values[i];\n\n      <span class=\"hljs-keyword\">if</span> (previousValue === currentValue) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">'Wrong order'</span>);\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'Foo bar!'</span>);\n  }\n};\n\ncomparators.addComparator(<span class=\"hljs-keyword\">new</span> MyComparator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"form-handlers\"></a><a href=\"#form-handlers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Form handlers</h3>\n<p>Form handlers allows you to fill the form inputs and check value of filled fields</p>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { handlers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> MyHandler {\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.registerFieldType = <span class=\"hljs-literal\">false</span>;\n    <span class=\"hljs-keyword\">this</span>.fieldType = <span class=\"hljs-string\">'default'</span>;\n  }\n\n  isSatisfiedBy(element, elementName) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(elementName === <span class=\"hljs-string\">'someElementName'</span>);\n  }\n \n  handleFill(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].clear().then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n          <span class=\"hljs-keyword\">return</span> page[elementName].sendKeys(desiredValue);\n        });\n      }\n    );\n  }\n\n  handleCheck(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].getAttribute(<span class=\"hljs-string\">'value'</span>).then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">value</span>) </span>{\n          <span class=\"hljs-keyword\">if</span> (value === desiredValue) {\n            <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve();\n          }\n\n          <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Expected <span class=\"hljs-subst\">${desiredValue}</span> got <span class=\"hljs-subst\">${value}</span> for text input element <span class=\"hljs-subst\">${elementName}</span>`</span>);\n        });\n      }\n    );\n  }\n};\n\nhandlers.addHandler(<span class=\"hljs-keyword\">new</span> MyHandler());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"transformers\"></a><a href=\"#transformers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Transformers</h3>\n<p>Transformers can be used in steps <code>When I fill the &quot;form&quot; form with:</code> and <code>And the &quot;joinOurStoreForm&quot; form is filled with:</code>.</p>\n<p>Existing transformers:</p>\n<ul>\n<li>generators (prefix: <code>g:</code>)</li>\n<li>dictionaries (prefix: <code>d:</code>)</li>\n<li>variableStore (prefix: <code>v:</code>)\nTransformers can be used in mentioned steps by using specific 'prefix', parameters are sent after <code>:</code> sign.\nExample:\n<code>g:generatorName:param:param</code></li>\n</ul>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { transformers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyTransformer</span> </span>{\n\n  isSatisfiedBy(prefix) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-string\">'yourPrefix:'</span> === prefix;\n  }\n\n  transform(value) {\n    <span class=\"hljs-comment\">//code</span>\n  }\n}\ntransformers.addTransformer(<span class=\"hljs-keyword\">new</span> MyTransformer());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"email-checking-service\"></a><a href=\"#email-checking-service\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Email checking service</h3>\n<p>You can easily check emails with Kakunin. By default we give you MailTrap client implementation, but you can easily add your own client.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { emailService } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyEmailService</span> </span>{\n  <span class=\"hljs-comment\">//you have access to full kakunin config</span>\n  isSatisfiedBy(config) {\n    <span class=\"hljs-keyword\">return</span> config.email.type === <span class=\"hljs-string\">'my-custom-email-service'</span>;\n  }\n  \n  <span class=\"hljs-comment\">//method used to clear emails before tests</span>\n  clearInbox() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to get emails - this method should return emails in format described below</span>\n  getEmails() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to retrive atachments for given email - should return attachments in format described below</span>\n  getAttachments(email) {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to mark given email as read</span>\n  markAsRead(email) {\n    ...\n  }\n}\n\nemailService.addAdapter(<span class=\"hljs-keyword\">new</span> MyEmailService());\n</code></pre>\n<p>Emails should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"subject\"</span>: <span class=\"hljs-string\">\"SMTP e-mail test\"</span>,\n      <span class=\"hljs-string\">\"sent_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.567+03:00\"</span>,\n      <span class=\"hljs-string\">\"from_email\"</span>: <span class=\"hljs-string\">\"me@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"from_name\"</span>: <span class=\"hljs-string\">\"Private Person\"</span>,\n      <span class=\"hljs-string\">\"to_email\"</span>: <span class=\"hljs-string\">\"test@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"to_name\"</span>: <span class=\"hljs-string\">\"A Test User\"</span>,\n      <span class=\"hljs-string\">\"html_body\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"text_body\"</span>: <span class=\"hljs-string\">\"This is a test e-mail message.\\r\\n\"</span>,\n      <span class=\"hljs-string\">\"email_size\"</span>: <span class=\"hljs-number\">193</span>,\n      <span class=\"hljs-string\">\"is_read\"</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.576+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:09.232+03:00\"</span>,\n      <span class=\"hljs-string\">\"sent_at_timestamp\"</span>: <span class=\"hljs-number\">1377448326</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap email format.</p>\n<p>Attachments should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"id\"</span>: <span class=\"hljs-number\">1737</span>,\n      <span class=\"hljs-string\">\"message_id\"</span>: <span class=\"hljs-number\">54508</span>,\n      <span class=\"hljs-string\">\"filename\"</span>: <span class=\"hljs-string\">\"Photos.png\"</span>,\n      <span class=\"hljs-string\">\"attachment_type\"</span>: <span class=\"hljs-string\">\"attachment\"</span>,\n      <span class=\"hljs-string\">\"content_type\"</span>: <span class=\"hljs-string\">\"image/png\"</span>,\n      <span class=\"hljs-string\">\"content_id\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"transfer_encoding\"</span>: <span class=\"hljs-string\">\"base64\"</span>,\n      <span class=\"hljs-string\">\"attachment_size\"</span>: <span class=\"hljs-number\">213855</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"attachment_human_size\"</span>: <span class=\"hljs-string\">\"210 KB\"</span>,\n      <span class=\"hljs-string\">\"download_path\"</span>: <span class=\"hljs-string\">\"/api/v1/inboxes/3/messages/54508/attachments/1737/download\"</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap attachment format.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/transformers\"><span class=\"arrow-prev\">← </span><span>Transformers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/cross-browser\"><span>Cross-browser testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#internal-services\">Internal services</a><ul class=\"toc-headings\"><li><a href=\"#regex-builder\">Regex builder</a></li><li><a href=\"#variable-store\">Variable store</a></li><li><a href=\"#user-provider\">User provider</a></li></ul></li><li><a href=\"#adding-custom-code\">Adding custom code</a><ul class=\"toc-headings\"><li><a href=\"#custom-step\">Custom step</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#matchers\">Matchers</a></li><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#comparators\">Comparators</a></li><li><a href=\"#form-handlers\">Form handlers</a></li><li><a href=\"#transformers\">Transformers</a></li><li><a href=\"#email-checking-service\">Email checking service</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/how-it-works/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>How it works · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"How it works · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">How it works</h1></header><article><div><span><p>Kakunin is built with <code>no-js</code> experience in mind. Because of that you're able to test even complicated apps just\nby knowing Kakunin (Gherkin) steps and a few good practices.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"concepts\"></a><a href=\"#concepts\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Concepts</h2>\n<p>Kakunin uses <code>cucumber-js</code> internally, because of that all tests (or rather scenarios) are using <code>Gherkin</code> as a &quot;programming&quot;\nlanguage.</p>\n<p>A simple scenario could look like this:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>This is how most of Kakunin test scenarios look like.</p>\n<p>There are a few concepts to be explained.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h2>\n<p>Page object is a code representation of a page displayed in browser. Kakunin has built-in <code>BasePage</code> page object, that you should extend.</p>\n<p>Page object contains information about page url, its elements, locators, but can also have some custom methods if necessary.</p>\n<p>A very simple example of Kakunin's Page Object could look like the following:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/dashboard'</span>;\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = DashboardPage;\n</code></pre>\n<p>As you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (<code>this.url</code>).</p>\n<p>This code should be saved inside <code>pages</code> directory in a file with <code>js</code> extension.\nNote that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n</code></pre>\n<p>expects that there is a file named <code>dashboard.js</code> inside the <code>pages</code> directory.</p>\n<p>Every step that we are using is somehow connected to an object called <code>currentPage</code>. This object value is set to a\npage object that we expect to be on.</p>\n<p>This is done by two kinds of steps:</p>\n<ul>\n<li><code>Then the &quot;dashboard&quot; page is displayed</code> - this one checks if current url in browser is the same as the one inside Page Object and changes a value of the <code>currentPage</code> field\nto this page object</li>\n<li><code>When I visit the &quot;dashboard&quot; page</code> - this one goes to the url specified in Page Object and attaches the Page Object to the <code>currentPage</code> field as above</li>\n</ul>\n<p>This concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods.\nFor example, having the following code:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>The step named <code>And I click the &quot;profileButton&quot; element</code> is executed in context of <code>dashboard</code> Page Object, thus we can assume that <code>profileButton</code> should be defined inside the\n<code>pages/dashboard.js</code> file.</p>\n<p>At the same time the step <code>And the &quot;myName&quot; element is visible</code> is executed in context of <code>myProfile</code>, so <code>myName</code> should be defined in <code>pages/myProfile.js</code> file.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"elements-and-locators\"></a><a href=\"#elements-and-locators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Elements and locators</h2>\n<p>The second concept that you have to understand are elements and locators.</p>\n<p>Every element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:\n<code>And the &quot;myName&quot; element is visible</code>.</p>\n<p>Defining elements is very simple. Let's say we have such page object:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>Elements should be defined inside <code>constructor</code> method. Let's add element for <code>myName</code>:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n        \n        <span class=\"hljs-keyword\">this</span>.myName = element(by.css('.myName'));\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>As you see we added a single line <code>this.myName = element(by.css('.myName'));</code>.</p>\n<p><code>by.css('.myName')</code> - is a locator, this is a standard protractor syntax, you can read more on protractors documentation</p>\n<p>By joining <code>element</code> method with a locator, we created element to be used by our steps.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"compare-urls-examples\"></a><a href=\"#compare-urls-examples\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Compare URLs examples:</h2>\n<table>\n<thead>\n<tr><th>Page Object URL</th><th>Current Browser URL</th><th>Base URL - config file</th><th>Results</th></tr>\n</thead>\n<tbody>\n<tr><td><a href=\"http://localhost:8080/incorrect-data\">http://localhost:8080/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/incorrect-data/\">http://localhost:8080/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data\">http://google/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/tabular-data\">http://google/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data/\">http://google/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data/</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"http://incorrect.com\">http://incorrect.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data/\">http://localhost:8080/tabular-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl\">https://google.pl</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://google.com/:example/:name\">https://google.com/:example/:name</a></td><td><a href=\"https://google.com/example/janek\">https://google.com/example/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/:name\">https://google.com/:name</a></td><td><a href=\"https://google.com/janek\">https://google.com/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/account/:username/settings/display\">https://google.com/account/:username/settings/display</a></td><td><a href=\"https://google.com/account/janek/settings/display\">https://google.com/account/janek/settings/display</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType/something</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://incorrect-host/account/settings/:userType/something\">https://incorrect-host/account/settings/:userType/something</a></td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://google.com/account/settings/user\">https://google.com/account/settings/user</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>TRUE</td></tr>\n</tbody>\n</table>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/configuration\"><span class=\"arrow-prev\">← </span><span>Configuration</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/matchers\"><span>Matchers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#concepts\">Concepts</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#elements-and-locators\">Elements and locators</a></li><li><a href=\"#compare-urls-examples\">Compare URLs examples:</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/how-it-works.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>How it works · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"How it works · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">How it works</h1></header><article><div><span><p>Kakunin is built with <code>no-js</code> experience in mind. Because of that you're able to test even complicated apps just\nby knowing Kakunin (Gherkin) steps and a few good practices.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"concepts\"></a><a href=\"#concepts\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Concepts</h2>\n<p>Kakunin uses <code>cucumber-js</code> internally, because of that all tests (or rather scenarios) are using <code>Gherkin</code> as a &quot;programming&quot;\nlanguage.</p>\n<p>A simple scenario could look like this:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>This is how most of Kakunin test scenarios look like.</p>\n<p>There are a few concepts to be explained.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h2>\n<p>Page object is a code representation of a page displayed in browser. Kakunin has built-in <code>BasePage</code> page object, that you should extend.</p>\n<p>Page object contains information about page url, its elements, locators, but can also have some custom methods if necessary.</p>\n<p>A very simple example of Kakunin's Page Object could look like the following:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/dashboard'</span>;\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = DashboardPage;\n</code></pre>\n<p>As you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (<code>this.url</code>).</p>\n<p>This code should be saved inside <code>pages</code> directory in a file with <code>js</code> extension.\nNote that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n</code></pre>\n<p>expects that there is a file named <code>dashboard.js</code> inside the <code>pages</code> directory.</p>\n<p>Every step that we are using is somehow connected to an object called <code>currentPage</code>. This object value is set to a\npage object that we expect to be on.</p>\n<p>This is done by two kinds of steps:</p>\n<ul>\n<li><code>Then the &quot;dashboard&quot; page is displayed</code> - this one checks if current url in browser is the same as the one inside Page Object and changes a value of the <code>currentPage</code> field\nto this page object</li>\n<li><code>When I visit the &quot;dashboard&quot; page</code> - this one goes to the url specified in Page Object and attaches the Page Object to the <code>currentPage</code> field as above</li>\n</ul>\n<p>This concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods.\nFor example, having the following code:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>The step named <code>And I click the &quot;profileButton&quot; element</code> is executed in context of <code>dashboard</code> Page Object, thus we can assume that <code>profileButton</code> should be defined inside the\n<code>pages/dashboard.js</code> file.</p>\n<p>At the same time the step <code>And the &quot;myName&quot; element is visible</code> is executed in context of <code>myProfile</code>, so <code>myName</code> should be defined in <code>pages/myProfile.js</code> file.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"elements-and-locators\"></a><a href=\"#elements-and-locators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Elements and locators</h2>\n<p>The second concept that you have to understand are elements and locators.</p>\n<p>Every element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:\n<code>And the &quot;myName&quot; element is visible</code>.</p>\n<p>Defining elements is very simple. Let's say we have such page object:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>Elements should be defined inside <code>constructor</code> method. Let's add element for <code>myName</code>:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n        \n        <span class=\"hljs-keyword\">this</span>.myName = element(by.css('.myName'));\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>As you see we added a single line <code>this.myName = element(by.css('.myName'));</code>.</p>\n<p><code>by.css('.myName')</code> - is a locator, this is a standard protractor syntax, you can read more on protractors documentation</p>\n<p>By joining <code>element</code> method with a locator, we created element to be used by our steps.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"compare-urls-examples\"></a><a href=\"#compare-urls-examples\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Compare URLs examples:</h2>\n<table>\n<thead>\n<tr><th>Page Object URL</th><th>Current Browser URL</th><th>Base URL - config file</th><th>Results</th></tr>\n</thead>\n<tbody>\n<tr><td><a href=\"http://localhost:8080/incorrect-data\">http://localhost:8080/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/incorrect-data/\">http://localhost:8080/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data\">http://google/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/tabular-data\">http://google/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data/\">http://google/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data/</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"http://incorrect.com\">http://incorrect.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data/\">http://localhost:8080/tabular-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl\">https://google.pl</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://google.com/:example/:name\">https://google.com/:example/:name</a></td><td><a href=\"https://google.com/example/janek\">https://google.com/example/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/:name\">https://google.com/:name</a></td><td><a href=\"https://google.com/janek\">https://google.com/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/account/:username/settings/display\">https://google.com/account/:username/settings/display</a></td><td><a href=\"https://google.com/account/janek/settings/display\">https://google.com/account/janek/settings/display</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType/something</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://incorrect-host/account/settings/:userType/something\">https://incorrect-host/account/settings/:userType/something</a></td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://google.com/account/settings/user\">https://google.com/account/settings/user</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>TRUE</td></tr>\n</tbody>\n</table>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/configuration\"><span class=\"arrow-prev\">← </span><span>Configuration</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/matchers\"><span>Matchers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#concepts\">Concepts</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#elements-and-locators\">Elements and locators</a></li><li><a href=\"#compare-urls-examples\">Compare URLs examples:</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Getting started · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## About Kakunin\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Getting started · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## About Kakunin\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Getting started</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"about-kakunin\"></a><a href=\"#about-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About Kakunin</h2>\n<p>Kakunin is a Protractor extension created by The Software House sp. z o.o. and Takamol Holding. It allows you\nto write e2e test scenarios with a help of Gherkin language and JavaScript for all kind of applications - Angular, React and others.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"installation\"></a><a href=\"#installation\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Installation</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project</p>\n<pre><code class=\"hljs css language-bash\">mkdir my_project\n</code></pre>\n<p>Go to project directory</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env protractor webdriver-manager kakunin  --save\n</code></pre>\n<p>Inside <code>package.json</code> file; add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-json\">\"kakunin\": \"cross-env NODE_ENV=prod kakunin\"\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ul>\n<li>Create kakunin project</li>\n</ul>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>The above command will run Kakunin's init script.</p>\n<ul>\n<li>Answer what kind of app you're going to test (<code>default: AngularJS</code>)</li>\n<li>Enter URL where your tested app will be running (<code>default: http://localhost:3000</code>)</li>\n<li>Choose if you plan to use some emails checking service (<code>default: none</code>)</li>\n</ul>\n<p>Also, there is a possibility to answer these question by a command line.</p>\n<pre><code class=\"hljs css language-text\">npm run kakunin init -- --baseUrl https://google.com --type otherWeb --emailType none\n</code></pre>\n<p>Available parameters: <code>baseUrl</code>, <code>type</code>, <code>emailType</code>, <code>emailApiKey</code>, <code>emailInboxId</code>.\nYou will not be asked about question that you already answered by a command.</p>\n<p>After the init process, a project files should be automatically created in your directory.</p>\n<p>This is an example of a console output after the init process is completed:</p>\n<pre><code class=\"hljs css language-text\">Created file at path /Users/example-user/projects/test/kakunin.conf.js\nCreated directory at path /Users/<user>/TSHProjects/test/reports\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report/features\nCreated directory at path /Users/<user>/TSHProjects/test/reports/performance\nCreated directory at path /Users/<user>/TSHProjects/test/downloads\nCreated directory at path /Users/example-user/projects/test/data\nCreated directory at path /Users/example-user/projects/test/features\nCreated directory at path /Users/example-user/projects/test/pages\nCreated directory at path /Users/example-user/projects/test/matchers\nCreated directory at path /Users/example-user/projects/test/generators\nCreated directory at path /Users/example-user/projects/test/form_handlers\nCreated directory at path /Users/example-user/projects/test/step_definitions\nCreated directory at path /Users/example-user/projects/test/comparators\nCreated directory at path /Users/example-user/projects/test/dictionaries\nCreated directory at path /Users/example-user/projects/test/regexes\nCreated directory at path /Users/example-user/projects/test/hooks\nCreated directory at path /Users/example-user/projects/test/transformers\nCreated directory at path /Users/example-user/projects/test/emails\nCreated file at path /Users/example-user/projects/test/downloads/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/features/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/performance/.gitkeep\nCreated file at path /Users/example-user/projects/test/features/example.feature\nCreated file at path /Users/example-user/projects/test/pages/page.js\nCreated file at path /Users/example-user/projects/test/matchers/matcher.js\nCreated file at path /Users/example-user/projects/test/generators/generator.js\nCreated file at path /Users/example-user/projects/test/step_definitions/steps.js\nCreated file at path /Users/example-user/projects/test/regexes/regex.js\nCreated file at path /Users/example-user/projects/test/hooks/hook.js\n</code></pre>\n<p>And you're set! Now you can run the tests using Kakunin:</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"commands\"></a><a href=\"#commands\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Commands</h2>\n<ul>\n<li><p>Create a new project by answering few simple questions (you can pass additional parameter to enter advanced mode where you can configure all Kakunin options by yourself)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init [-- --advanced]\n</code></pre></li>\n<li><p>Run test scenarios</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags @someTag\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code> and <code>@otherTag</code> at the same time</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"@someTag and @otherTag\"</span>\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code> or <code>@otherTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"@someTag or @otherTag\"</span>\n</code></pre></li>\n<li><p>Run only scenarios not tagged by <code>@someTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"not @someTag\"</span>\n</code></pre></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting--tips\"></a><a href=\"#troubleshooting--tips\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting &amp; Tips</h2>\n<p>In order to make cucumber steps autosuggestion work properly in JetBrains tools, make sure your project is <code>ECMAScript 6</code> compatible and you have <code>cucumberjs</code> plugin installed.\nDue to non-resolved issue in Jetbrains editors (<a href=\"https://youtrack.jetbrains.com/issue/WEB-11505\">see here</a>) we'll have to do one more step:</p>\n<p>Go to <code>step_definitions</code> directory</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-built_in\">cd</span> step_definitions\n</code></pre>\n<p>Paste this code into terminal and restart your IDE:</p>\n<p>For Linux/MacOs:</p>\n<pre><code class=\"hljs css language-bash\">ln -s ../node_modules/kakunin/dist/step_definitions/elements.js kakunin-elements.js\nln -s ../node_modules/kakunin/dist/step_definitions/debug.js kakunin-debug.js\nln -s ../node_modules/kakunin/dist/step_definitions/file.js kakunin-file.js\nln -s ../node_modules/kakunin/dist/step_definitions/form.js kakunin-form.js\nln -s ../node_modules/kakunin/dist/step_definitions/email.js kakunin-email.js\nln -s ../node_modules/kakunin/dist/step_definitions/generators.js kakunin-generators.js\nln -s ../node_modules/kakunin/dist/step_definitions/navigation.js kakunin-navigation.js \nln -s ../node_modules/kakunin/dist/step_definitions/performance.js kakunin-performance.js \n</code></pre>\n<p>For Windows 8+: (you have to do this as administrator)</p>\n<pre><code class=\"hljs css language-bash\">mklink kakunin-elements.js ../node_modules/kakunin/dist/step_definitions/elements.js\nmklink kakunin-debug.js ../node_modules/kakunin/dist/step_definitions/debug.js \nmklink kakunin-file.js ../node_modules/kakunin/dist/step_definitions/file.js \nmklink kakunin-form.js ../node_modules/kakunin/dist/step_definitions/form.js \nmklink kakunin-email.js ../node_modules/kakunin/dist/step_definitions/email.js\nmklink kakunin-generators.js ../node_modules/kakunin/dist/step_definitions/generators.js \nmklink kakunin-navigation.js ../node_modules/kakunin/dist/step_definitions/navigation.js \nmklink kakunin-performance.js ../node_modules/kakunin/dist/step_definitions/performance.js \n</code></pre>\n<p>Keep in mind that <code>mklink</code> is not available in older Windows distributions.</p>\n<p>This will create symlinks inside <code>step_definitions</code> directory and make <code>cucumberjs</code> plugin recognize kakunin built-in steps.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/quickstart\"><span class=\"arrow-prev\">← </span><span>Quick start</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/configuration\"><span>Configuration</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#about-kakunin\">About Kakunin</a></li><li><a href=\"#installation\">Installation</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#commands\">Commands</a></li><li><a href=\"#troubleshooting--tips\">Troubleshooting &amp; Tips</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/matchers/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Matchers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Matchers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Matchers</h1></header><article><div><span><p>Matchers allows you to check if a element content matches your expectation.</p>\n<p>For example you can check if a value has a specified pattern or if a button is clickable.</p>\n<p>Using matcher is very straightforward, for example: <code>f:isClickable</code>.</p>\n<p>Matchers can be used in most of the steps related to checking content (with exception of checking form values).</p>\n<p>Kakunin comes with a set of built in matchers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"visibility-matcher\"></a><a href=\"#visibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Visibility matcher</h2>\n<p><code>f:isVisible</code> - checks if element is visible (must be in viewport and cannot be hidden behind any other element)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"invisibility-matcher\"></a><a href=\"#invisibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Invisibility matcher</h2>\n<p><code>f:isNotVisible</code> - checks if element is not visible</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"present-matcher\"></a><a href=\"#present-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Present matcher</h2>\n<p><code>f:isPresent</code> - checks if element is in html code (does not have to be visible)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"clickable-matcher\"></a><a href=\"#clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clickable matcher</h2>\n<p><code>f:isClickable</code> - checks if element is clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"not-clickable-matcher\"></a><a href=\"#not-clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Not clickable matcher</h2>\n<p><code>f:isNotClickable</code> - checks if element is not clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"attribute-matcher\"></a><a href=\"#attribute-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attribute matcher</h2>\n<p><code>attribute:attributeName:regexName</code> - allows to check if element has attribute with a name specified by <code>attributeName</code> and it has to\nhave a format passing <code>regexName</code></p>\n<p>For example, if there is an element:</p>\n<p><code>&lt;p custom-attribute=&quot;123123&quot;&gt;some value&lt;/p&gt;</code></p>\n<p>you can check if attribute is an number by running: <code>attribute:custom-attribute:number</code></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-matcher\"></a><a href=\"#regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex matcher</h2>\n<p><code>r:regexName</code> - allows you to run a <code>regexName</code> against a text value of element</p>\n<p>Regexes have to be specified inside <code>regex</code> directory or be a kakunin built ones:</p>\n<p><code>notEmpty</code> - there must be a value\n<code>number</code> - must be a number</p>\n<p>You can add your own matchers. In order to do so please read <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"text-matcher\"></a><a href=\"#text-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Text matcher</h2>\n<p><code>t:text you are looking for</code> - allows you to check if an element contains a expected text</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"current-date-matcher\"></a><a href=\"#current-date-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Current date matcher</h2>\n<p><code>f:currentDate:{format}</code> - allows you to generate current date, <code>{format}</code> is optional, by default <code>DD-MM-YYYY</code></p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/how-it-works\"><span class=\"arrow-prev\">← </span><span>How it works</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/transformers\"><span>Transformers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#visibility-matcher\">Visibility matcher</a></li><li><a href=\"#invisibility-matcher\">Invisibility matcher</a></li><li><a href=\"#present-matcher\">Present matcher</a></li><li><a href=\"#clickable-matcher\">Clickable matcher</a></li><li><a href=\"#not-clickable-matcher\">Not clickable matcher</a></li><li><a href=\"#attribute-matcher\">Attribute matcher</a></li><li><a href=\"#regex-matcher\">Regex matcher</a></li><li><a href=\"#text-matcher\">Text matcher</a></li><li><a href=\"#current-date-matcher\">Current date matcher</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/matchers.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Matchers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Matchers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Matchers</h1></header><article><div><span><p>Matchers allows you to check if a element content matches your expectation.</p>\n<p>For example you can check if a value has a specified pattern or if a button is clickable.</p>\n<p>Using matcher is very straightforward, for example: <code>f:isClickable</code>.</p>\n<p>Matchers can be used in most of the steps related to checking content (with exception of checking form values).</p>\n<p>Kakunin comes with a set of built in matchers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"visibility-matcher\"></a><a href=\"#visibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Visibility matcher</h2>\n<p><code>f:isVisible</code> - checks if element is visible (must be in viewport and cannot be hidden behind any other element)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"invisibility-matcher\"></a><a href=\"#invisibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Invisibility matcher</h2>\n<p><code>f:isNotVisible</code> - checks if element is not visible</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"present-matcher\"></a><a href=\"#present-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Present matcher</h2>\n<p><code>f:isPresent</code> - checks if element is in html code (does not have to be visible)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"clickable-matcher\"></a><a href=\"#clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clickable matcher</h2>\n<p><code>f:isClickable</code> - checks if element is clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"not-clickable-matcher\"></a><a href=\"#not-clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Not clickable matcher</h2>\n<p><code>f:isNotClickable</code> - checks if element is not clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"attribute-matcher\"></a><a href=\"#attribute-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attribute matcher</h2>\n<p><code>attribute:attributeName:regexName</code> - allows to check if element has attribute with a name specified by <code>attributeName</code> and it has to\nhave a format passing <code>regexName</code></p>\n<p>For example, if there is an element:</p>\n<p><code>&lt;p custom-attribute=&quot;123123&quot;&gt;some value&lt;/p&gt;</code></p>\n<p>you can check if attribute is an number by running: <code>attribute:custom-attribute:number</code></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-matcher\"></a><a href=\"#regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex matcher</h2>\n<p><code>r:regexName</code> - allows you to run a <code>regexName</code> against a text value of element</p>\n<p>Regexes have to be specified inside <code>regex</code> directory or be a kakunin built ones:</p>\n<p><code>notEmpty</code> - there must be a value\n<code>number</code> - must be a number</p>\n<p>You can add your own matchers. In order to do so please read <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"text-matcher\"></a><a href=\"#text-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Text matcher</h2>\n<p><code>t:text you are looking for</code> - allows you to check if an element contains a expected text</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"current-date-matcher\"></a><a href=\"#current-date-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Current date matcher</h2>\n<p><code>f:currentDate:{format}</code> - allows you to generate current date, <code>{format}</code> is optional, by default <code>DD-MM-YYYY</code></p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/how-it-works\"><span class=\"arrow-prev\">← </span><span>How it works</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/transformers\"><span>Transformers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#visibility-matcher\">Visibility matcher</a></li><li><a href=\"#invisibility-matcher\">Invisibility matcher</a></li><li><a href=\"#present-matcher\">Present matcher</a></li><li><a href=\"#clickable-matcher\">Clickable matcher</a></li><li><a href=\"#not-clickable-matcher\">Not clickable matcher</a></li><li><a href=\"#attribute-matcher\">Attribute matcher</a></li><li><a href=\"#regex-matcher\">Regex matcher</a></li><li><a href=\"#text-matcher\">Text matcher</a></li><li><a href=\"#current-date-matcher\">Current date matcher</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/parallel-testing/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Parallel testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"There is a possibility to run tests in parallel.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Parallel testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"There is a possibility to run tests in parallel.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Parallel testing</h1></header><article><div><span><p>There is a possibility to run tests in parallel.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-execute\"></a><a href=\"#how-to-execute\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to execute</h2>\n<p>Use a command <code>npm run kakunin -- --parallel &lt;number of instances&gt;</code> where <code>number of instances</code> is a number.</p>\n<p>Example:</p>\n<ul>\n<li><code>npm run kakunin -- --chrome --parallel 2</code></li>\n</ul>\n<p><span style=\"color:red\">Keep in mind that the merged report is available in the <code>reports/report/index.html</code> file. text</span></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"specify-pattern-per-each-instance\"></a><a href=\"#specify-pattern-per-each-instance\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Specify pattern per each instance</h2>\n<ul>\n<li><code>npm run kakunin -- --parallel &lt;number of instances&gt; --pattern &lt;regex to much feature&gt; --pattern &lt;regex to much feature&gt;</code></li>\n</ul>\n<p>Keep in mind that:</p>\n<ul>\n<li>the number given in <code>parallel</code> must be equal to passed <code>patterns</code></li>\n<li><code>&lt;number of instances&gt;</code> is a number of instances of the specified browser</li>\n<li><code>&lt;regex&gt;</code> is a pattern that is used to specify the list of specs that will be executed in each of the instances</li>\n</ul>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h2>\n<ol>\n<li>Running more than one instance in <code>Firefox</code> is not possible now (fix in-progress).</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/cross-browser\"><span class=\"arrow-prev\">← </span><span>Cross-browser testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/performance-testing\"><span>Performance testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#how-to-execute\">How to execute</a></li><li><a href=\"#specify-pattern-per-each-instance\">Specify pattern per each instance</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/parallel-testing.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Parallel testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"There is a possibility to run tests in parallel.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Parallel testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"There is a possibility to run tests in parallel.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Parallel testing</h1></header><article><div><span><p>There is a possibility to run tests in parallel.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-execute\"></a><a href=\"#how-to-execute\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to execute</h2>\n<p>Use a command <code>npm run kakunin -- --parallel &lt;number of instances&gt;</code> where <code>number of instances</code> is a number.</p>\n<p>Example:</p>\n<ul>\n<li><code>npm run kakunin -- --chrome --parallel 2</code></li>\n</ul>\n<p><span style=\"color:red\">Keep in mind that the merged report is available in the <code>reports/report/index.html</code> file. text</span></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"specify-pattern-per-each-instance\"></a><a href=\"#specify-pattern-per-each-instance\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Specify pattern per each instance</h2>\n<ul>\n<li><code>npm run kakunin -- --parallel &lt;number of instances&gt; --pattern &lt;regex to much feature&gt; --pattern &lt;regex to much feature&gt;</code></li>\n</ul>\n<p>Keep in mind that:</p>\n<ul>\n<li>the number given in <code>parallel</code> must be equal to passed <code>patterns</code></li>\n<li><code>&lt;number of instances&gt;</code> is a number of instances of the specified browser</li>\n<li><code>&lt;regex&gt;</code> is a pattern that is used to specify the list of specs that will be executed in each of the instances</li>\n</ul>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h2>\n<ol>\n<li>Running more than one instance in <code>Firefox</code> is not possible now (fix in-progress).</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/cross-browser\"><span class=\"arrow-prev\">← </span><span>Cross-browser testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/performance-testing\"><span>Performance testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#how-to-execute\">How to execute</a></li><li><a href=\"#specify-pattern-per-each-instance\">Specify pattern per each instance</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/performance-testing/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Performance testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Performance testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Performance testing</h1></header><article><div><span><p>Performance testing is possible thanks to <code>browsermob-proxy</code>.</p>\n<p>It saves all data from network tab (Google Chrome console) which is generated during the test.</p>\n<p>There is a possibility to compare <code>TTFB</code> value with a maximum given one.</p>\n<p><code>TTFB</code> (Time to first byte) measures the duration from the client making an HTTP request to the first byte of a response being received by the client's browser.</p>\n<p>More details can be found in documentation - <code>Built-in steps</code> section.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"what-needs-to-be-done\"></a><a href=\"#what-needs-to-be-done\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What needs to be done?</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"get-started\"></a><a href=\"#get-started\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get started</h2>\n<ol>\n<li><p>Download <code>browsermob-proxy</code> from <code>https://github.com/lightbody/browsermob-proxy</code></p></li>\n<li><p>Navigate in terminal to the catalog</p></li>\n<li><p>Use following command to start the REST API</p></li>\n</ol>\n<pre><code class=\"hljs\">./browsermob-proxy -port <span class=\"hljs-number\">8887</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ol>\n<li>Add <code>browsermob-proxy</code> configuration to <code>kakunin.conf.js</code></li>\n</ol>\n<p>You can use one of the following methods to configure browsermob-proxy:</p>\n<ul>\n<li><p><code>npm run kakunin init -- --advanced</code> and go through the process</p></li>\n<li><p>or add it manually to the config file:</p></li>\n</ul>\n<pre><code class=\"hljs css language-javascript\">    <span class=\"hljs-string\">\"browserMob\"</span>: {\n      <span class=\"hljs-string\">\"serverPort\"</span>: <span class=\"hljs-number\">8887</span>,\n      <span class=\"hljs-string\">\"port\"</span>: <span class=\"hljs-number\">8888</span>,\n      <span class=\"hljs-string\">\"host\"</span>: <span class=\"hljs-string\">\"localhost\"</span>\n    }\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h2>\n<ol>\n<li><p><code>performance steps</code> must be used in the scenario where you are testing performance</p></li>\n<li><p>Scenario must have a tag <code>@performance</code></p></li>\n<li><p>Run tests with special parameter:</p></li>\n</ol>\n<pre><code class=\"hljs\">npm <span class=\"hljs-built_in\">run</span> kakunin <span class=\"hljs-comment\">-- --performance</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"results\"></a><a href=\"#results\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Results</h2>\n<ol>\n<li><code>.har</code> files are saved in catalog <code>reports/performance/*.har</code></li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/parallel-testing\"><span class=\"arrow-prev\">← </span><span>Parallel testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/docker\"><span>Docker</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#get-started\">Get started</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#results\">Results</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/performance-testing.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Performance testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Performance testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Performance testing</h1></header><article><div><span><p>Performance testing is possible thanks to <code>browsermob-proxy</code>.</p>\n<p>It saves all data from network tab (Google Chrome console) which is generated during the test.</p>\n<p>There is a possibility to compare <code>TTFB</code> value with a maximum given one.</p>\n<p><code>TTFB</code> (Time to first byte) measures the duration from the client making an HTTP request to the first byte of a response being received by the client's browser.</p>\n<p>More details can be found in documentation - <code>Built-in steps</code> section.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"what-needs-to-be-done\"></a><a href=\"#what-needs-to-be-done\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What needs to be done?</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"get-started\"></a><a href=\"#get-started\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get started</h2>\n<ol>\n<li><p>Download <code>browsermob-proxy</code> from <code>https://github.com/lightbody/browsermob-proxy</code></p></li>\n<li><p>Navigate in terminal to the catalog</p></li>\n<li><p>Use following command to start the REST API</p></li>\n</ol>\n<pre><code class=\"hljs\">./browsermob-proxy -port <span class=\"hljs-number\">8887</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ol>\n<li>Add <code>browsermob-proxy</code> configuration to <code>kakunin.conf.js</code></li>\n</ol>\n<p>You can use one of the following methods to configure browsermob-proxy:</p>\n<ul>\n<li><p><code>npm run kakunin init -- --advanced</code> and go through the process</p></li>\n<li><p>or add it manually to the config file:</p></li>\n</ul>\n<pre><code class=\"hljs css language-javascript\">    <span class=\"hljs-string\">\"browserMob\"</span>: {\n      <span class=\"hljs-string\">\"serverPort\"</span>: <span class=\"hljs-number\">8887</span>,\n      <span class=\"hljs-string\">\"port\"</span>: <span class=\"hljs-number\">8888</span>,\n      <span class=\"hljs-string\">\"host\"</span>: <span class=\"hljs-string\">\"localhost\"</span>\n    }\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h2>\n<ol>\n<li><p><code>performance steps</code> must be used in the scenario where you are testing performance</p></li>\n<li><p>Scenario must have a tag <code>@performance</code></p></li>\n<li><p>Run tests with special parameter:</p></li>\n</ol>\n<pre><code class=\"hljs\">npm <span class=\"hljs-built_in\">run</span> kakunin <span class=\"hljs-comment\">-- --performance</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"results\"></a><a href=\"#results\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Results</h2>\n<ol>\n<li><code>.har</code> files are saved in catalog <code>reports/performance/*.har</code></li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/parallel-testing\"><span class=\"arrow-prev\">← </span><span>Parallel testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/docker\"><span>Docker</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#get-started\">Get started</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#results\">Results</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/quickstart/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Quick start · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Quick start · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Quick start</h1></header><article><div><span><p>As a quick demonstration of the framework let's test the\n<a href=\"http://todomvc.com/examples/react/#/\">React variant of TodoMVC</a> project.\nOf course other testing other frameworks is possible, you can try it\nby yourself!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"install-packages\"></a><a href=\"#install-packages\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install packages</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project and enter it</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-variable\">$mkdir</span> my_project\n<span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env protractor webdriver-manager kakunin  --save\n</code></pre>\n<p>Inside <code>package.json</code> file add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-js\">...\n<span class=\"hljs-string\">\"scripts\"</span>: {\n  <span class=\"hljs-string\">\"kakunin\"</span>: <span class=\"hljs-string\">\"cross-env NODE_ENV=prod kakunin\"</span>\n},\n...\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configure-kakunin\"></a><a href=\"#configure-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure Kakunin</h2>\n<p>Run initialization command</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>Answer literally few questions:</p>\n<pre><code class=\"hljs css language-text\">What kind of application would you like to test? : otherWeb\n        \nWhat is base url? [http://localhost:3000]: http://todomvc.com\n           \nWhat kind of email service would you like to use?: none\n</code></pre>\n<p>And you're set! Now let's write some test!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"test-the-app\"></a><a href=\"#test-the-app\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the app</h2>\n<p>Create a page object that will contain instructions on how to locate elements in the projects.\nCreate a file <code>pages/main.js</code>:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MainPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n\n        <span class=\"hljs-comment\">// define the main url for the page</span>\n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/examples/react/#/'</span>;\n\n        <span class=\"hljs-comment\">// whole form tag</span>\n        <span class=\"hljs-keyword\">this</span>.addTodoForm = $(<span class=\"hljs-string\">'.todoapp'</span>);\n\n        <span class=\"hljs-comment\">// input field</span>\n        <span class=\"hljs-keyword\">this</span>.todoInput = $(<span class=\"hljs-string\">'input.new-todo'</span>);\n\n        <span class=\"hljs-comment\">// list of currently added todos</span>\n        <span class=\"hljs-keyword\">this</span>.todos = $$(<span class=\"hljs-string\">'.todo-list .view'</span>);\n        <span class=\"hljs-keyword\">this</span>.todoLabel = by.css(<span class=\"hljs-string\">'label'</span>);\n\n        <span class=\"hljs-comment\">// first todo item in a list</span>\n        <span class=\"hljs-keyword\">this</span>.firstTodoItem = <span class=\"hljs-keyword\">this</span>.todos.get(<span class=\"hljs-number\">0</span>);\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MainPage;\n</code></pre>\n<p>Now that we have prepared the locators, we can start writing our test. Let's test adding new todo item.</p>\n<p>Create a file named: <code>features/adding_todo.feature</code> with the following contents:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 1\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n\n</code></pre>\n<p>And that's it! All you have to do now is to run the test and watch the magic happens ;)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<p>The tests may run quite fast so you might not been able to see that it\nreally works as expected. To check if the todo items has been really\nadded to the list, let's use a simple hack - let's pause the running\ntest right after the todo has been added.</p>\n<p>To do that, let's upgrade our Scenario. Update the file:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> Another todo item! </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 2\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n        <span class=\"hljs-keyword\">Then</span> I wait for <span class=\"hljs-string\">\"5\"</span> seconds\n\n</code></pre>\n<p>As you can see, we've added 1 new step that waits for a second before\n&quot;pressing&quot; the <code>enter</code> key. We've also added a second todo item with\na short pause at the end of the test so you can see the changes.</p>\n<p>If you want to see what can we do more with the TodoMVC project, take a look\nat the <code>example</code> dir, where you'll find a complete set of test for the project.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/index\"><span>Getting started</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#install-packages\">Install packages</a></li><li><a href=\"#configure-kakunin\">Configure Kakunin</a></li><li><a href=\"#test-the-app\">Test the app</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/quickstart.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Quick start · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Quick start · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Quick start</h1></header><article><div><span><p>As a quick demonstration of the framework let's test the\n<a href=\"http://todomvc.com/examples/react/#/\">React variant of TodoMVC</a> project.\nOf course other testing other frameworks is possible, you can try it\nby yourself!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"install-packages\"></a><a href=\"#install-packages\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install packages</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project and enter it</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-variable\">$mkdir</span> my_project\n<span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env protractor webdriver-manager kakunin  --save\n</code></pre>\n<p>Inside <code>package.json</code> file add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-js\">...\n<span class=\"hljs-string\">\"scripts\"</span>: {\n  <span class=\"hljs-string\">\"kakunin\"</span>: <span class=\"hljs-string\">\"cross-env NODE_ENV=prod kakunin\"</span>\n},\n...\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configure-kakunin\"></a><a href=\"#configure-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure Kakunin</h2>\n<p>Run initialization command</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>Answer literally few questions:</p>\n<pre><code class=\"hljs css language-text\">What kind of application would you like to test? : otherWeb\n        \nWhat is base url? [http://localhost:3000]: http://todomvc.com\n           \nWhat kind of email service would you like to use?: none\n</code></pre>\n<p>And you're set! Now let's write some test!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"test-the-app\"></a><a href=\"#test-the-app\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the app</h2>\n<p>Create a page object that will contain instructions on how to locate elements in the projects.\nCreate a file <code>pages/main.js</code>:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MainPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n\n        <span class=\"hljs-comment\">// define the main url for the page</span>\n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/examples/react/#/'</span>;\n\n        <span class=\"hljs-comment\">// whole form tag</span>\n        <span class=\"hljs-keyword\">this</span>.addTodoForm = $(<span class=\"hljs-string\">'.todoapp'</span>);\n\n        <span class=\"hljs-comment\">// input field</span>\n        <span class=\"hljs-keyword\">this</span>.todoInput = $(<span class=\"hljs-string\">'input.new-todo'</span>);\n\n        <span class=\"hljs-comment\">// list of currently added todos</span>\n        <span class=\"hljs-keyword\">this</span>.todos = $$(<span class=\"hljs-string\">'.todo-list .view'</span>);\n        <span class=\"hljs-keyword\">this</span>.todoLabel = by.css(<span class=\"hljs-string\">'label'</span>);\n\n        <span class=\"hljs-comment\">// first todo item in a list</span>\n        <span class=\"hljs-keyword\">this</span>.firstTodoItem = <span class=\"hljs-keyword\">this</span>.todos.get(<span class=\"hljs-number\">0</span>);\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MainPage;\n</code></pre>\n<p>Now that we have prepared the locators, we can start writing our test. Let's test adding new todo item.</p>\n<p>Create a file named: <code>features/adding_todo.feature</code> with the following contents:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 1\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n\n</code></pre>\n<p>And that's it! All you have to do now is to run the test and watch the magic happens ;)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<p>The tests may run quite fast so you might not been able to see that it\nreally works as expected. To check if the todo items has been really\nadded to the list, let's use a simple hack - let's pause the running\ntest right after the todo has been added.</p>\n<p>To do that, let's upgrade our Scenario. Update the file:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> Another todo item! </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 2\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n        <span class=\"hljs-keyword\">Then</span> I wait for <span class=\"hljs-string\">\"5\"</span> seconds\n\n</code></pre>\n<p>As you can see, we've added 1 new step that waits for a second before\n&quot;pressing&quot; the <code>enter</code> key. We've also added a second todo item with\na short pause at the end of the test so you can see the changes.</p>\n<p>If you want to see what can we do more with the TodoMVC project, take a look\nat the <code>example</code> dir, where you'll find a complete set of test for the project.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/index\"><span>Getting started</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#install-packages\">Install packages</a></li><li><a href=\"#configure-kakunin\">Configure Kakunin</a></li><li><a href=\"#test-the-app\">Test the app</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-debug/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Debug · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps for debugging application:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Debug · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps for debugging application:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Debug</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-for-debugging-application\"></a><a href=\"#steps-for-debugging-application\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps for debugging application:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-pause\"></a><a href=\"#i-pause\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I pause</code></h2>\n<p>Pauses tests execution and allows to continue manually by pressing combination of <code>ctrl+c</code> inside terminal.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-seconds-seconds\"></a><a href=\"#i-wait-for-seconds-seconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:seconds&quot; seconds</code></h2>\n<p>Waits with execution of next step for an amount provided by parameter <code>:seconds</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-start-performance-monitor-mode\"></a><a href=\"#i-start-performance-monitor-mode\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I start performance monitor mode</code></h2>\n<p>It starts performance monitor mode.</p>\n<p>Keep in mind that REST API must be started on the port which must configured in <code>kakunin.conf.js</code> - <code>serverPort: 8887</code>.</p>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-save-performance-report-file-as-filename\"></a><a href=\"#i-save-performance-report-file-as-filename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I save performance report file as &quot;fileName&quot;</code></h2>\n<p>It saves <code>.har</code> file with a name <code>fileName</code> in <code>reports/performance</code> catalog.</p>\n<p>For example: <code>exampleReport-1511470954552.har</code></p>\n<p>Data is generated during the test - network tab in Chrome Chrome console.</p>\n<p>Keep in mind:</p>\n<ul>\n<li><p><code>I start performance monitor mode</code> must be used before this step</p></li>\n<li><p><code>browserMob.port</code> must be configured in <code>kakunin.conf.js</code></p></li>\n<li><p><code>browserMob.host</code> must be configured in <code>kakunin.conf.js</code></p></li>\n</ul>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"></a><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></h2>\n<p>It compares every <code>TTFB</code> timing value from previously saved <code>.har</code> report with a <code>maxTiming</code> value.</p>\n<p>Slow requests are listed in your terminal in red colour.</p>\n<p>Keep in mind that <code>I start performance monitor mode</code> and <code>I save performance report file as &quot;fileName&quot;</code> steps must be executed before this one!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-generators\"><span class=\"arrow-prev\">← </span><span>Generators</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-pause\"><code>I pause</code></a></li><li><a href=\"#i-wait-for-seconds-seconds\"><code>I wait for &quot;:seconds&quot; seconds</code></a></li><li><a href=\"#i-start-performance-monitor-mode\"><code>I start performance monitor mode</code></a></li><li><a href=\"#i-save-performance-report-file-as-filename\"><code>I save performance report file as &quot;fileName&quot;</code></a></li><li><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-debug.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Debug · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps for debugging application:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Debug · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps for debugging application:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Debug</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-for-debugging-application\"></a><a href=\"#steps-for-debugging-application\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps for debugging application:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-pause\"></a><a href=\"#i-pause\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I pause</code></h2>\n<p>Pauses tests execution and allows to continue manually by pressing combination of <code>ctrl+c</code> inside terminal.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-seconds-seconds\"></a><a href=\"#i-wait-for-seconds-seconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:seconds&quot; seconds</code></h2>\n<p>Waits with execution of next step for an amount provided by parameter <code>:seconds</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-start-performance-monitor-mode\"></a><a href=\"#i-start-performance-monitor-mode\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I start performance monitor mode</code></h2>\n<p>It starts performance monitor mode.</p>\n<p>Keep in mind that REST API must be started on the port which must configured in <code>kakunin.conf.js</code> - <code>serverPort: 8887</code>.</p>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-save-performance-report-file-as-filename\"></a><a href=\"#i-save-performance-report-file-as-filename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I save performance report file as &quot;fileName&quot;</code></h2>\n<p>It saves <code>.har</code> file with a name <code>fileName</code> in <code>reports/performance</code> catalog.</p>\n<p>For example: <code>exampleReport-1511470954552.har</code></p>\n<p>Data is generated during the test - network tab in Chrome Chrome console.</p>\n<p>Keep in mind:</p>\n<ul>\n<li><p><code>I start performance monitor mode</code> must be used before this step</p></li>\n<li><p><code>browserMob.port</code> must be configured in <code>kakunin.conf.js</code></p></li>\n<li><p><code>browserMob.host</code> must be configured in <code>kakunin.conf.js</code></p></li>\n</ul>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"></a><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></h2>\n<p>It compares every <code>TTFB</code> timing value from previously saved <code>.har</code> report with a <code>maxTiming</code> value.</p>\n<p>Slow requests are listed in your terminal in red colour.</p>\n<p>Keep in mind that <code>I start performance monitor mode</code> and <code>I save performance report file as &quot;fileName&quot;</code> steps must be executed before this one!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-generators\"><span class=\"arrow-prev\">← </span><span>Generators</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-pause\"><code>I pause</code></a></li><li><a href=\"#i-wait-for-seconds-seconds\"><code>I wait for &quot;:seconds&quot; seconds</code></a></li><li><a href=\"#i-start-performance-monitor-mode\"><code>I start performance monitor mode</code></a></li><li><a href=\"#i-save-performance-report-file-as-filename\"><code>I save performance report file as &quot;fileName&quot;</code></a></li><li><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-elements/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Elements · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with elements:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Elements · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with elements:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Elements</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-elements\"></a><a href=\"#steps-used-to-interact-with-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with elements:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll through infinite scroll mechanism.</p>\n<p>The <code>:elementName</code> is a name of a selector for loading trigger.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-expectedconditionname-of-the-elementname-element\"></a><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></h2>\n<p>Waits till element <code>:elementName</code> from <code>this.currentPage</code> meets criteria specified by <code>:expectedConditionName</code>.</p>\n<p>You can use any of the Protractor's expected condition:</p>\n<ul>\n<li><code>visibilityOf</code></li>\n<li><code>invisibilityOf</code></li>\n</ul>\n<p>etc.</p>\n<p>Read more in Protractor's API documentation.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-the-elementname-element-to-disappear\"></a><a href=\"#i-wait-for-the-elementname-element-to-disappear\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for the &quot;:elementName&quot; element to disappear</code></h2>\n<p>Waits till element <code>:elementName</code> disappears.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-scroll-to-the-elementname-element\"></a><a href=\"#i-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Scrolls to element <code>:elementName</code> of <code>this.currentPage</code>. The element will be on bottom of the page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element-1\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll till <code>:elementName</code> is visible. Useful for infinite scrolling functionality.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-press-the-keyname-key\"></a><a href=\"#i-press-the-keyname-key\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I press the &quot;:keyName&quot; key</code></h2>\n<p>Performs a key press operation on <code>:keyName</code> key.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-click-the-elementname-element\"></a><a href=\"#i-click-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I click the &quot;:elementName&quot; element</code></h2>\n<p>Performs a click action on element <code>:elementName</code> from `this.currentPage'</p>\n<p>The child element must be specified by <code>:elementName</code> and must be available in <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the text from element <code>:elementName</code> of <code>this.currentPage</code> under the <code>:variableName</code> so you can use it later.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-update-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Updates the variable <code>:variableName</code> value by value from element <code>:elementName</code> of <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the part of the element <code>:elementName</code> text, that matches the <code>:matchingRegex</code> under the <code>:variableName</code> for later use.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-visible\"></a><a href=\"#the-elementname-element-is-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is visible</code></h2>\n<p>Checks if element <code>:elementName</code> is visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-not-visible\"></a><a href=\"#the-elementname-element-is-not-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is not visible</code></h2>\n<p>Checks if element <code>:elementName</code> is available in HTML DOM but is not visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-disabled\"></a><a href=\"#the-elementname-element-is-disabled\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot; element is disabled</code></h2>\n<p>Checks if element is disabled</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-table-tablerow-rows-as-variablename-with-columns\"></a><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></h2>\n<p>Allows to store a row specified columns from a table <code>:tableRow</code> and save it under <code>:variableName</code> as an array of objects.</p>\n<p>This step requires a table of columns elements, for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I store table <span class=\"hljs-string\">\"someRow\"</span> rows as <span class=\"hljs-string\">\"someVariable\"</span> with columns:\n  |<span class=\"hljs-string\"> firstName </span>|\n  |<span class=\"hljs-string\"> lastName  </span>|\n  |<span class=\"hljs-string\"> id        </span>|\n</code></pre>\n<p>In order to make it work there must be not only array element <code>this.someRow = $$('.rows')</code> in <code>this.currentPage</code>, but also\nelement <code>this.firstName = $('.firstName');</code> and so on.</p>\n<p>The result of this step is an array of:</p>\n<pre><code class=\"hljs css language-javascript\">[\n  [\n    <span class=\"hljs-string\">'firsRowFirstNameValue'</span>,\n    <span class=\"hljs-string\">'firsRowLastNameValue'</span>\n    <span class=\"hljs-string\">'firsRowIdValue'</span>\n  ]\n  ...\n]\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-following-elements-in-table-elementname\"></a><a href=\"#there-are-following-elements-in-table-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are following elements in table &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content.</p>\n<p>This steps allows you to specify an array of child elements that will be checked against expected values.</p>\n<p>For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are following elements in table <span class=\"hljs-string\">\"myTable\"</span>:\n  |<span class=\"hljs-string\"> id  </span>|<span class=\"hljs-string\"> firstName </span>|<span class=\"hljs-string\"> lastName </span>|\n  |<span class=\"hljs-string\"> t:1 </span>|<span class=\"hljs-string\"> t:Adam    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n  |<span class=\"hljs-string\"> t:2 </span>|<span class=\"hljs-string\"> t:John    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n</code></pre>\n<p>First row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.</p>\n<p>This step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.</p>\n<p>We can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-following-elements-for-element-elementname\"></a><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>Allows to check if a number of elements is the one that we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are <span class=\"hljs-string\">\"equal 5\"</span> following elements for element <span class=\"hljs-string\">\"myList\"</span>:\n  |<span class=\"hljs-string\"> viewButton </span>|<span class=\"hljs-string\"> f:isClickable </span>|\n  |<span class=\"hljs-string\"> id         </span>|<span class=\"hljs-string\"> r:idRegex     </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.viewButton = $('button.viewButton');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-value-matcher\"></a><a href=\"#there-is-element-elementname-with-value-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> has a value that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-value-matchername\"></a><a href=\"#there-is-no-element-elementname-with-value-matchername\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></h2>\n<p>Allows to check if there is no <code>:elementName</code> that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-elementname-elements\"></a><a href=\"#there-are-numberexpression-elementname-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></h2>\n<p>Allows to check if a number of <code>:elementName</code> elements is the same as we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p><code>:elementName</code> should be specified as an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"every-elementname-element-should-have-the-same-value-for-element-columnelementname\"></a><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></h2>\n<p>Allows to check if every row defined by <code>:elementName</code> has the same value for a column <code>:columnElementName</code>.</p>\n<p><code>:elementName</code> must be an array of elements</p>\n<p><code>:columnElementName</code> must be an element, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code> and we can specify column element\n<code>this.myColumn = $('td');</code>. This allows us to write:</p>\n<p><code>every &quot;myElement&quot; element should have the same value for element &quot;myColumn&quot;</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should have an item with values:</code></h2>\n<p>Allows to check if any of the child elements of <code>:elementName</code> have a specified content (one matching element is enough). Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:1 </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-not-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-not-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should not have an item with values:</code></h2>\n<p>Allows to check if the child elements of <code>:elementName</code> have a different content than that given in the table. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:does-not-exist </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-drag-elementdrag-element-and-drop-over-elementdrop-element\"></a><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></h2>\n<p>Clicks on <code>:elementDrag</code> and moves it onto <code>:elementDrop</code> while left mouse button is pressed, and then release it.</p>\n<p>Note: This step is not working on HTML5!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-forms\"><span class=\"arrow-prev\">← </span><span>Forms</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-files\"><span>Files</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-infinitely-scroll-to-the-elementname-element\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\"><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-the-elementname-element-to-disappear\"><code>I wait for the &quot;:elementName&quot; element to disappear</code></a></li><li><a href=\"#i-scroll-to-the-elementname-element\"><code>I scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-press-the-keyname-key\"><code>I press the &quot;:keyName&quot; key</code></a></li><li><a href=\"#i-click-the-elementname-element\"><code>I click the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\"><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#the-elementname-element-is-visible\"><code>the &quot;:elementName&quot;&quot; element is visible</code></a></li><li><a href=\"#the-elementname-element-is-not-visible\"><code>the &quot;:elementName&quot;&quot; element is not visible</code></a></li><li><a href=\"#the-elementname-element-is-disabled\"><code>the &quot;:elementName&quot; element is disabled</code></a></li><li><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\"><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></a></li><li><a href=\"#there-are-following-elements-in-table-elementname\"><code>there are following elements in table &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\"><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-is-element-elementname-with-value-matcher\"><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-with-value-matchername\"><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></a></li><li><a href=\"#there-are-numberexpression-elementname-elements\"><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></a></li><li><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\"><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></a></li><li><a href=\"#the-element-elementname-should-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should have an item with values:</code></a></li><li><a href=\"#the-element-elementname-should-not-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should not have an item with values:</code></a></li><li><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\"><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-elements.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Elements · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with elements:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Elements · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with elements:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Elements</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-elements\"></a><a href=\"#steps-used-to-interact-with-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with elements:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll through infinite scroll mechanism.</p>\n<p>The <code>:elementName</code> is a name of a selector for loading trigger.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-expectedconditionname-of-the-elementname-element\"></a><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></h2>\n<p>Waits till element <code>:elementName</code> from <code>this.currentPage</code> meets criteria specified by <code>:expectedConditionName</code>.</p>\n<p>You can use any of the Protractor's expected condition:</p>\n<ul>\n<li><code>visibilityOf</code></li>\n<li><code>invisibilityOf</code></li>\n</ul>\n<p>etc.</p>\n<p>Read more in Protractor's API documentation.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-the-elementname-element-to-disappear\"></a><a href=\"#i-wait-for-the-elementname-element-to-disappear\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for the &quot;:elementName&quot; element to disappear</code></h2>\n<p>Waits till element <code>:elementName</code> disappears.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-scroll-to-the-elementname-element\"></a><a href=\"#i-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Scrolls to element <code>:elementName</code> of <code>this.currentPage</code>. The element will be on bottom of the page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element-1\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll till <code>:elementName</code> is visible. Useful for infinite scrolling functionality.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-press-the-keyname-key\"></a><a href=\"#i-press-the-keyname-key\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I press the &quot;:keyName&quot; key</code></h2>\n<p>Performs a key press operation on <code>:keyName</code> key.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-click-the-elementname-element\"></a><a href=\"#i-click-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I click the &quot;:elementName&quot; element</code></h2>\n<p>Performs a click action on element <code>:elementName</code> from `this.currentPage'</p>\n<p>The child element must be specified by <code>:elementName</code> and must be available in <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the text from element <code>:elementName</code> of <code>this.currentPage</code> under the <code>:variableName</code> so you can use it later.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-update-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Updates the variable <code>:variableName</code> value by value from element <code>:elementName</code> of <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the part of the element <code>:elementName</code> text, that matches the <code>:matchingRegex</code> under the <code>:variableName</code> for later use.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-visible\"></a><a href=\"#the-elementname-element-is-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is visible</code></h2>\n<p>Checks if element <code>:elementName</code> is visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-not-visible\"></a><a href=\"#the-elementname-element-is-not-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is not visible</code></h2>\n<p>Checks if element <code>:elementName</code> is available in HTML DOM but is not visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-disabled\"></a><a href=\"#the-elementname-element-is-disabled\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot; element is disabled</code></h2>\n<p>Checks if element is disabled</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-table-tablerow-rows-as-variablename-with-columns\"></a><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></h2>\n<p>Allows to store a row specified columns from a table <code>:tableRow</code> and save it under <code>:variableName</code> as an array of objects.</p>\n<p>This step requires a table of columns elements, for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I store table <span class=\"hljs-string\">\"someRow\"</span> rows as <span class=\"hljs-string\">\"someVariable\"</span> with columns:\n  |<span class=\"hljs-string\"> firstName </span>|\n  |<span class=\"hljs-string\"> lastName  </span>|\n  |<span class=\"hljs-string\"> id        </span>|\n</code></pre>\n<p>In order to make it work there must be not only array element <code>this.someRow = $$('.rows')</code> in <code>this.currentPage</code>, but also\nelement <code>this.firstName = $('.firstName');</code> and so on.</p>\n<p>The result of this step is an array of:</p>\n<pre><code class=\"hljs css language-javascript\">[\n  [\n    <span class=\"hljs-string\">'firsRowFirstNameValue'</span>,\n    <span class=\"hljs-string\">'firsRowLastNameValue'</span>\n    <span class=\"hljs-string\">'firsRowIdValue'</span>\n  ]\n  ...\n]\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-following-elements-in-table-elementname\"></a><a href=\"#there-are-following-elements-in-table-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are following elements in table &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content.</p>\n<p>This steps allows you to specify an array of child elements that will be checked against expected values.</p>\n<p>For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are following elements in table <span class=\"hljs-string\">\"myTable\"</span>:\n  |<span class=\"hljs-string\"> id  </span>|<span class=\"hljs-string\"> firstName </span>|<span class=\"hljs-string\"> lastName </span>|\n  |<span class=\"hljs-string\"> t:1 </span>|<span class=\"hljs-string\"> t:Adam    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n  |<span class=\"hljs-string\"> t:2 </span>|<span class=\"hljs-string\"> t:John    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n</code></pre>\n<p>First row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.</p>\n<p>This step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.</p>\n<p>We can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-following-elements-for-element-elementname\"></a><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>Allows to check if a number of elements is the one that we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are <span class=\"hljs-string\">\"equal 5\"</span> following elements for element <span class=\"hljs-string\">\"myList\"</span>:\n  |<span class=\"hljs-string\"> viewButton </span>|<span class=\"hljs-string\"> f:isClickable </span>|\n  |<span class=\"hljs-string\"> id         </span>|<span class=\"hljs-string\"> r:idRegex     </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.viewButton = $('button.viewButton');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-value-matcher\"></a><a href=\"#there-is-element-elementname-with-value-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> has a value that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-value-matchername\"></a><a href=\"#there-is-no-element-elementname-with-value-matchername\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></h2>\n<p>Allows to check if there is no <code>:elementName</code> that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-elementname-elements\"></a><a href=\"#there-are-numberexpression-elementname-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></h2>\n<p>Allows to check if a number of <code>:elementName</code> elements is the same as we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p><code>:elementName</code> should be specified as an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"every-elementname-element-should-have-the-same-value-for-element-columnelementname\"></a><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></h2>\n<p>Allows to check if every row defined by <code>:elementName</code> has the same value for a column <code>:columnElementName</code>.</p>\n<p><code>:elementName</code> must be an array of elements</p>\n<p><code>:columnElementName</code> must be an element, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code> and we can specify column element\n<code>this.myColumn = $('td');</code>. This allows us to write:</p>\n<p><code>every &quot;myElement&quot; element should have the same value for element &quot;myColumn&quot;</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should have an item with values:</code></h2>\n<p>Allows to check if any of the child elements of <code>:elementName</code> have a specified content (one matching element is enough). Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:1 </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-not-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-not-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should not have an item with values:</code></h2>\n<p>Allows to check if the child elements of <code>:elementName</code> have a different content than that given in the table. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:does-not-exist </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-drag-elementdrag-element-and-drop-over-elementdrop-element\"></a><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></h2>\n<p>Clicks on <code>:elementDrag</code> and moves it onto <code>:elementDrop</code> while left mouse button is pressed, and then release it.</p>\n<p>Note: This step is not working on HTML5!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-forms\"><span class=\"arrow-prev\">← </span><span>Forms</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-files\"><span>Files</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-infinitely-scroll-to-the-elementname-element\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\"><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-the-elementname-element-to-disappear\"><code>I wait for the &quot;:elementName&quot; element to disappear</code></a></li><li><a href=\"#i-scroll-to-the-elementname-element\"><code>I scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-press-the-keyname-key\"><code>I press the &quot;:keyName&quot; key</code></a></li><li><a href=\"#i-click-the-elementname-element\"><code>I click the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\"><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#the-elementname-element-is-visible\"><code>the &quot;:elementName&quot;&quot; element is visible</code></a></li><li><a href=\"#the-elementname-element-is-not-visible\"><code>the &quot;:elementName&quot;&quot; element is not visible</code></a></li><li><a href=\"#the-elementname-element-is-disabled\"><code>the &quot;:elementName&quot; element is disabled</code></a></li><li><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\"><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></a></li><li><a href=\"#there-are-following-elements-in-table-elementname\"><code>there are following elements in table &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\"><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-is-element-elementname-with-value-matcher\"><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-with-value-matchername\"><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></a></li><li><a href=\"#there-are-numberexpression-elementname-elements\"><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></a></li><li><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\"><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></a></li><li><a href=\"#the-element-elementname-should-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should have an item with values:</code></a></li><li><a href=\"#the-element-elementname-should-not-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should not have an item with values:</code></a></li><li><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\"><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-files/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Files · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with files:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Files · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with files:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Files</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-files\"></a><a href=\"#steps-used-to-interact-with-files\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with files:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-should-be-downloaded\"></a><a href=\"#the-file-filename-should-be-downloaded\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; should be downloaded</code></h2>\n<p>Checks if a file with name <code>:fileName</code> was downloaded.</p>\n<p>This step does not support matchers or regular expressions, so the name must be exact match. However you can use\nvariable store here.</p>\n<p>Let's assume there is a variable <code>myFile</code> with a value <code>super-file</code> in variable store.</p>\n<p>You can write <code>the file &quot;v:myFile.zip&quot; should be downloaded</code> to check if a file <code>super-file.zip</code> was downloaded.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-contains-table-data-stored-under-variablename-variable\"></a><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></h2>\n<p>This step allows you to compare an xls/xlsx file <code>:fileName</code> with an existing data stored under <code>:variableName</code> variable.</p>\n<p>The data under <code>:variableName</code> must be an array of objects representing each row of file.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-elements\"><span class=\"arrow-prev\">← </span><span>Elements</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-generators\"><span>Generators</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#the-file-filename-should-be-downloaded\"><code>the file &quot;:fileName&quot; should be downloaded</code></a></li><li><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\"><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-files.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Files · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with files:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Files · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with files:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Files</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-files\"></a><a href=\"#steps-used-to-interact-with-files\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with files:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-should-be-downloaded\"></a><a href=\"#the-file-filename-should-be-downloaded\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; should be downloaded</code></h2>\n<p>Checks if a file with name <code>:fileName</code> was downloaded.</p>\n<p>This step does not support matchers or regular expressions, so the name must be exact match. However you can use\nvariable store here.</p>\n<p>Let's assume there is a variable <code>myFile</code> with a value <code>super-file</code> in variable store.</p>\n<p>You can write <code>the file &quot;v:myFile.zip&quot; should be downloaded</code> to check if a file <code>super-file.zip</code> was downloaded.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-contains-table-data-stored-under-variablename-variable\"></a><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></h2>\n<p>This step allows you to compare an xls/xlsx file <code>:fileName</code> with an existing data stored under <code>:variableName</code> variable.</p>\n<p>The data under <code>:variableName</code> must be an array of objects representing each row of file.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-elements\"><span class=\"arrow-prev\">← </span><span>Elements</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-generators\"><span>Generators</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#the-file-filename-should-be-downloaded\"><code>the file &quot;:fileName&quot; should be downloaded</code></a></li><li><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\"><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-forms/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Forms · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to fill forms:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Forms · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to fill forms:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Forms</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-fill-forms\"></a><a href=\"#steps-used-to-fill-forms\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to fill forms:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-fill-the-formname-form-with\"></a><a href=\"#i-fill-the-formname-form-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I fill the &quot;:formName&quot; form with:</code></h2>\n<p>Allows to fill the form with the name <code>:formName</code> and values provided as an array of inputs and values. The element with name <code>:formName</code> must be defined inside the\n<code>currentPage</code> page object.</p>\n<p>Input and values should be provided as an array for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> value to be typed into field        </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> value to be typed into textarea     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> radio value to be selected          </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> checkbox label value to be selected </span>|\n</code></pre>\n<p>By default we support all basic HTML field types (text inputs, checkboxes, radios, selects, files and textareas)</p>\n<p>In order to use the default handlers the elements you use as input must follow pattern:</p>\n<p>For inputs:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill</p>\n<p>For textareas:</p>\n<p><code>this.element = $('textarea')</code> - element should point at textarea you want to fill</p>\n<p>For file input:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill and value should a filename of file from <code>data</code> directory</p>\n<p>For selects:</p>\n<p><code>this.element = $('select')</code> - element should point at select and value should be an value of expected option</p>\n<p>For radios:</p>\n<p><code>this.element = $$('radio[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all radio input of given name and value should be an value of radio you wish to select</p>\n<p>For checkboxes:</p>\n<p>Checkbox should have a html like:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label</span>&gt;</span>\n  My checkbox\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"checkbox\"</span> <span class=\"hljs-attr\">name</span>=<span class=\"hljs-string\">\"some-name\"</span>/&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">label</span>&gt;</span>\n</code></pre>\n<p><code>this.element = $$('checkbox[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all checkboxes of given name and value should be a text from label of checkbox you want to fill</p>\n<p>You can use all kind of transformers to as a values for fields.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-formname-form-is-filled-with\"></a><a href=\"#the-formname-form-is-filled-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:formName&quot; form is filled with:</code></h2>\n<p>The same as <code>I fill the &quot;:formName&quot; form with:</code> but allows to check if a form is filled with a given set of values.</p>\n<p>You can use all kind of transformers to as a expected values for fields.</p>\n<p>The only difference is for file fields. You cannot check uploaded files just like that, however we prepared a special type of handler\nthat allow to check for some information related to a specific file.</p>\n<p>Let's assume that after upload we display an information with a file name of a uploaded file.</p>\n<p>You can use a special handler that requires to set a element with a postfix <code>Uploaded</code>. This will check if a value of that element is the same as you expected.</p>\n<p>For example you can write a step like this:</p>\n<pre><code class=\"hljs css language-gherkin\">the <span class=\"hljs-string\">\"myform\"</span> form is filled with:\n  |<span class=\"hljs-string\"> myFileUploaded </span>|<span class=\"hljs-string\"> file.txt </span>|\n</code></pre>\n<p>Keep in mind that the element name must end with <code>Uploaded</code> for example:</p>\n<p><code>this.myFileUploaded = $('p.some-file')</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-error-messages-should-be-displayed\"></a><a href=\"#the-error-messages-should-be-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the error messages should be displayed:</code></h2>\n<p>Allows you to specify the error messages that should be displayed for a specific elements.</p>\n<p>This step requires an array of format:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> my error message </span>|\n</code></pre>\n<p>You can use dictionaries in this step as follows:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> d:dictionaryName:dictionaryKey </span>|\n</code></pre>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-navigation\"><span class=\"arrow-prev\">← </span><span>Navigation</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-elements\"><span>Elements</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-fill-the-formname-form-with\"><code>I fill the &quot;:formName&quot; form with:</code></a></li><li><a href=\"#the-formname-form-is-filled-with\"><code>the &quot;:formName&quot; form is filled with:</code></a></li><li><a href=\"#the-error-messages-should-be-displayed\"><code>the error messages should be displayed:</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-forms.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Forms · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to fill forms:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Forms · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to fill forms:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Forms</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-fill-forms\"></a><a href=\"#steps-used-to-fill-forms\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to fill forms:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-fill-the-formname-form-with\"></a><a href=\"#i-fill-the-formname-form-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I fill the &quot;:formName&quot; form with:</code></h2>\n<p>Allows to fill the form with the name <code>:formName</code> and values provided as an array of inputs and values. The element with name <code>:formName</code> must be defined inside the\n<code>currentPage</code> page object.</p>\n<p>Input and values should be provided as an array for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> value to be typed into field        </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> value to be typed into textarea     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> radio value to be selected          </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> checkbox label value to be selected </span>|\n</code></pre>\n<p>By default we support all basic HTML field types (text inputs, checkboxes, radios, selects, files and textareas)</p>\n<p>In order to use the default handlers the elements you use as input must follow pattern:</p>\n<p>For inputs:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill</p>\n<p>For textareas:</p>\n<p><code>this.element = $('textarea')</code> - element should point at textarea you want to fill</p>\n<p>For file input:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill and value should a filename of file from <code>data</code> directory</p>\n<p>For selects:</p>\n<p><code>this.element = $('select')</code> - element should point at select and value should be an value of expected option</p>\n<p>For radios:</p>\n<p><code>this.element = $$('radio[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all radio input of given name and value should be an value of radio you wish to select</p>\n<p>For checkboxes:</p>\n<p>Checkbox should have a html like:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label</span>&gt;</span>\n  My checkbox\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"checkbox\"</span> <span class=\"hljs-attr\">name</span>=<span class=\"hljs-string\">\"some-name\"</span>/&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">label</span>&gt;</span>\n</code></pre>\n<p><code>this.element = $$('checkbox[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all checkboxes of given name and value should be a text from label of checkbox you want to fill</p>\n<p>You can use all kind of transformers to as a values for fields.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-formname-form-is-filled-with\"></a><a href=\"#the-formname-form-is-filled-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:formName&quot; form is filled with:</code></h2>\n<p>The same as <code>I fill the &quot;:formName&quot; form with:</code> but allows to check if a form is filled with a given set of values.</p>\n<p>You can use all kind of transformers to as a expected values for fields.</p>\n<p>The only difference is for file fields. You cannot check uploaded files just like that, however we prepared a special type of handler\nthat allow to check for some information related to a specific file.</p>\n<p>Let's assume that after upload we display an information with a file name of a uploaded file.</p>\n<p>You can use a special handler that requires to set a element with a postfix <code>Uploaded</code>. This will check if a value of that element is the same as you expected.</p>\n<p>For example you can write a step like this:</p>\n<pre><code class=\"hljs css language-gherkin\">the <span class=\"hljs-string\">\"myform\"</span> form is filled with:\n  |<span class=\"hljs-string\"> myFileUploaded </span>|<span class=\"hljs-string\"> file.txt </span>|\n</code></pre>\n<p>Keep in mind that the element name must end with <code>Uploaded</code> for example:</p>\n<p><code>this.myFileUploaded = $('p.some-file')</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-error-messages-should-be-displayed\"></a><a href=\"#the-error-messages-should-be-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the error messages should be displayed:</code></h2>\n<p>Allows you to specify the error messages that should be displayed for a specific elements.</p>\n<p>This step requires an array of format:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> my error message </span>|\n</code></pre>\n<p>You can use dictionaries in this step as follows:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> d:dictionaryName:dictionaryKey </span>|\n</code></pre>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-navigation\"><span class=\"arrow-prev\">← </span><span>Navigation</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-elements\"><span>Elements</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-fill-the-formname-form-with\"><code>I fill the &quot;:formName&quot; form with:</code></a></li><li><a href=\"#the-formname-form-is-filled-with\"><code>the &quot;:formName&quot; form is filled with:</code></a></li><li><a href=\"#the-error-messages-should-be-displayed\"><code>the error messages should be displayed:</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-generators/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Generators · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to generate values:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Generators · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to generate values:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Generators</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-generate-values\"></a><a href=\"#steps-used-to-generate-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to generate values:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-generate-random-generatorparamparam-as-variablename\"></a><a href=\"#i-generate-random-generatorparamparam-as-variablename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></h2>\n<p>Allows to generate a random value using the generator specified by <code>:generator:param:param</code>.</p>\n<p>The generator must be defined inside the any of the <code>generators</code> directories specified in <code>kakunin.conf.js</code> file <code>default: generators</code>.</p>\n<p>If the generator exists, then the value will be saved under the <code>:variableName</code> and can be accessed by:</p>\n<ul>\n<li><p>steps using variable store</p></li>\n<li><p>by calling <code>variableStore.getVariableValue(:variableName)</code></p></li>\n<li><p>by using variable store transformer on supported steps <code>v:variableName</code></p></li>\n</ul>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-files\"><span class=\"arrow-prev\">← </span><span>Files</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-debug\"><span>Debug</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-generate-random-generatorparamparam-as-variablename\"><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-generators.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Generators · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to generate values:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Generators · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to generate values:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Generators</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-generate-values\"></a><a href=\"#steps-used-to-generate-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to generate values:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-generate-random-generatorparamparam-as-variablename\"></a><a href=\"#i-generate-random-generatorparamparam-as-variablename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></h2>\n<p>Allows to generate a random value using the generator specified by <code>:generator:param:param</code>.</p>\n<p>The generator must be defined inside the any of the <code>generators</code> directories specified in <code>kakunin.conf.js</code> file <code>default: generators</code>.</p>\n<p>If the generator exists, then the value will be saved under the <code>:variableName</code> and can be accessed by:</p>\n<ul>\n<li><p>steps using variable store</p></li>\n<li><p>by calling <code>variableStore.getVariableValue(:variableName)</code></p></li>\n<li><p>by using variable store transformer on supported steps <code>v:variableName</code></p></li>\n</ul>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/steps-files\"><span class=\"arrow-prev\">← </span><span>Files</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-debug\"><span>Debug</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-generate-random-generatorparamparam-as-variablename\"><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-navigation/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Navigation · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used for navigation on page:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Navigation · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used for navigation on page:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Navigation</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-for-navigation-on-page\"></a><a href=\"#steps-used-for-navigation-on-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used for navigation on page:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page\"></a><a href=\"#i-visit-the-pagefilename-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page</code></h2>\n<p>Visits the url of the page object with <code>:pageFileName</code> name.</p>\n<p>In order to make it work we create a page object file with a name of <code>:pageFileName</code>.</p>\n<p>For example in case of: <code>I visit the &quot;myPage&quot; page</code> there should be a file <code>myPage.js</code> inside the <code>pages</code> directory.</p>\n<p>If we have a page object with a name <code>somePageObject.js</code> defined inside <code>pages</code> directory then:</p>\n<p><code>Given I visit the &quot;somePageObject&quot; page</code></p>\n<p>will set <code>this.currentPage</code> variable to <code>somePageObject</code> page and we should end up on <code>somePageObject</code> url.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page-with-parameters\"></a><a href=\"#i-visit-the-pagefilename-page-with-parameters\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></h2>\n<p>The same as <code>I visit the &quot;:pageFileName&quot; page</code> except allows to pass url parameters.</p>\n<p>If url of <code>myPage</code> is defined as <code>this.url = /orders/:orderId/products/:productId</code> then we can use this step to visit this page by:</p>\n<pre><code class=\"hljs css language-gherkin\">I visit the <span class=\"hljs-string\">\"myPage\"</span> page with parameters:\n    |<span class=\"hljs-string\"> orderId   </span>|<span class=\"hljs-string\"> 1 </span>|\n    |<span class=\"hljs-string\"> productId </span>|<span class=\"hljs-string\"> 2 </span>|\n</code></pre>\n<p>this will result in visiting the <code>/orders/1/product/2</code> page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-pagefilename-page-is-displayed\"></a><a href=\"#the-pagefilename-page-is-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:pageFileName&quot; page is displayed</code></h2>\n<p>Checks if current browser url matches url of <code>pageFileName</code> page object.</p>\n<p>If the url matches expected pattern then\n<code>this.currentPage</code> variable is set to <code>pageFileName</code> page object.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/docker\"><span class=\"arrow-prev\">← </span><span>Docker</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-forms\"><span>Forms</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-visit-the-pagefilename-page\"><code>I visit the &quot;:pageFileName&quot; page</code></a></li><li><a href=\"#i-visit-the-pagefilename-page-with-parameters\"><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></a></li><li><a href=\"#the-pagefilename-page-is-displayed\"><code>the &quot;:pageFileName&quot; page is displayed</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/steps-navigation.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Navigation · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used for navigation on page:\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Navigation · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used for navigation on page:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Navigation</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-for-navigation-on-page\"></a><a href=\"#steps-used-for-navigation-on-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used for navigation on page:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page\"></a><a href=\"#i-visit-the-pagefilename-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page</code></h2>\n<p>Visits the url of the page object with <code>:pageFileName</code> name.</p>\n<p>In order to make it work we create a page object file with a name of <code>:pageFileName</code>.</p>\n<p>For example in case of: <code>I visit the &quot;myPage&quot; page</code> there should be a file <code>myPage.js</code> inside the <code>pages</code> directory.</p>\n<p>If we have a page object with a name <code>somePageObject.js</code> defined inside <code>pages</code> directory then:</p>\n<p><code>Given I visit the &quot;somePageObject&quot; page</code></p>\n<p>will set <code>this.currentPage</code> variable to <code>somePageObject</code> page and we should end up on <code>somePageObject</code> url.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page-with-parameters\"></a><a href=\"#i-visit-the-pagefilename-page-with-parameters\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></h2>\n<p>The same as <code>I visit the &quot;:pageFileName&quot; page</code> except allows to pass url parameters.</p>\n<p>If url of <code>myPage</code> is defined as <code>this.url = /orders/:orderId/products/:productId</code> then we can use this step to visit this page by:</p>\n<pre><code class=\"hljs css language-gherkin\">I visit the <span class=\"hljs-string\">\"myPage\"</span> page with parameters:\n    |<span class=\"hljs-string\"> orderId   </span>|<span class=\"hljs-string\"> 1 </span>|\n    |<span class=\"hljs-string\"> productId </span>|<span class=\"hljs-string\"> 2 </span>|\n</code></pre>\n<p>this will result in visiting the <code>/orders/1/product/2</code> page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-pagefilename-page-is-displayed\"></a><a href=\"#the-pagefilename-page-is-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:pageFileName&quot; page is displayed</code></h2>\n<p>Checks if current browser url matches url of <code>pageFileName</code> page object.</p>\n<p>If the url matches expected pattern then\n<code>this.currentPage</code> variable is set to <code>pageFileName</code> page object.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/docker\"><span class=\"arrow-prev\">← </span><span>Docker</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/steps-forms\"><span>Forms</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-visit-the-pagefilename-page\"><code>I visit the &quot;:pageFileName&quot; page</code></a></li><li><a href=\"#i-visit-the-pagefilename-page-with-parameters\"><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></a></li><li><a href=\"#the-pagefilename-page-is-displayed\"><code>the &quot;:pageFileName&quot; page is displayed</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/transformers/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Transformers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Transformers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Transformers</h1></header><article><div><span><p>Transformers allow you to transform values passed to form steps.</p>\n<p>For example a select requires to pass a value <code>/options/1b30f17e-e445-4d28-a30c-dedad95829ab</code>. This one is quite unreadable, but with the help of transformers you are\nable to write it like this: <code>d:options:someOptionName</code>.</p>\n<p>In real-life example it will look similar to:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> d:someDictionary:someKey            </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> g:someGenerator                     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> v:someVariableName                  </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> standard value                      </span>|\n</code></pre>\n<p>There are 3 types of built-in transformers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h2>\n<p>Dictionaries allows you to transform a value A to value B using a simple key-&gt;value transformation.</p>\n<p>You can run a dictionary transformer by providing dictionary prefix <code>d:</code>, specifying the dictionary name and key that should be used as a value provider. For example:</p>\n<p><code>d:myDictionaryName:myDictionaryKey</code></p>\n<p>this example assumes that there is a dictionary that supports name <code>myDictionaryName</code> and it has <code>myDictionarKey</code> key.</p>\n<p>You can read about dictionaries in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h2>\n<p>Generators allows you to generate a value by using a specified generator.</p>\n<p>This can be done by: <code>g:generatorName</code>.</p>\n<p>If a generator supports parameters then you can specify them by:</p>\n<p><code>g:generatorName:param1:param2:...:paramN</code></p>\n<p>You can read more about generators in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h2>\n<p>Variable store allows you to fill the form with a value that was saved in previous steps of current running scenario.</p>\n<p>This can be done by:</p>\n<p><code>v:variableName</code></p>\n<p>You can read more about variable store in <code>Extending Kakunin</code> section</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/matchers\"><span class=\"arrow-prev\">← </span><span>Matchers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/extending\"><span>Extending Kakunin</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#variable-store\">Variable store</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/2.4.0/transformers.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Transformers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta name=\"docsearch:version\" content=\"2.4.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Transformers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.4.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/matchers\">Matchers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/2.4.0/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Transformers</h1></header><article><div><span><p>Transformers allow you to transform values passed to form steps.</p>\n<p>For example a select requires to pass a value <code>/options/1b30f17e-e445-4d28-a30c-dedad95829ab</code>. This one is quite unreadable, but with the help of transformers you are\nable to write it like this: <code>d:options:someOptionName</code>.</p>\n<p>In real-life example it will look similar to:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> d:someDictionary:someKey            </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> g:someGenerator                     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> v:someVariableName                  </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> standard value                      </span>|\n</code></pre>\n<p>There are 3 types of built-in transformers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h2>\n<p>Dictionaries allows you to transform a value A to value B using a simple key-&gt;value transformation.</p>\n<p>You can run a dictionary transformer by providing dictionary prefix <code>d:</code>, specifying the dictionary name and key that should be used as a value provider. For example:</p>\n<p><code>d:myDictionaryName:myDictionaryKey</code></p>\n<p>this example assumes that there is a dictionary that supports name <code>myDictionaryName</code> and it has <code>myDictionarKey</code> key.</p>\n<p>You can read about dictionaries in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h2>\n<p>Generators allows you to generate a value by using a specified generator.</p>\n<p>This can be done by: <code>g:generatorName</code>.</p>\n<p>If a generator supports parameters then you can specify them by:</p>\n<p><code>g:generatorName:param1:param2:...:paramN</code></p>\n<p>You can read more about generators in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h2>\n<p>Variable store allows you to fill the form with a value that was saved in previous steps of current running scenario.</p>\n<p>This can be done by:</p>\n<p><code>v:variableName</code></p>\n<p>You can read more about variable store in <code>Extending Kakunin</code> section</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/2.4.0/matchers\"><span class=\"arrow-prev\">← </span><span>Matchers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/2.4.0/extending\"><span>Extending Kakunin</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#variable-store\">Variable store</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/configuration/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Configuration · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## Kakunin config\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Configuration · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## Kakunin config\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Configuration</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"kakunin-config\"></a><a href=\"#kakunin-config\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Kakunin config</h2>\n<pre><code class=\"hljs\">module.exports = {\n    <span class=\"hljs-string\">\"browserWidth\"</span>: <span class=\"hljs-number\">1600</span>,\n    <span class=\"hljs-string\">\"browserHeight\"</span>: <span class=\"hljs-number\">900</span>,\n    <span class=\"hljs-string\">\"timeout\"</span>: <span class=\"hljs-number\">60</span>,\n    <span class=\"hljs-string\">\"maxEmailRepeats\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"intervalEmail\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"elementsVisibilityTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"waitForPageTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"downloadTimeout\"</span>: <span class=\"hljs-number\">30</span>,\n    <span class=\"hljs-string\">\"reports\"</span>: <span class=\"hljs-string\">\"/reports\"</span>,\n    <span class=\"hljs-string\">\"downloads\"</span>: <span class=\"hljs-string\">\"/downloads\"</span>,\n    <span class=\"hljs-string\">\"data\"</span>: <span class=\"hljs-string\">\"/data\"</span>,\n    <span class=\"hljs-string\">\"features\"</span>: [\n        <span class=\"hljs-string\">\"/features\"</span>\n    ],\n    <span class=\"hljs-string\">\"pages\"</span>: [\n        <span class=\"hljs-string\">\"/pages\"</span>\n    ],\n    <span class=\"hljs-string\">\"matchers\"</span>: [\n        <span class=\"hljs-string\">\"/matchers\"</span>\n    ],\n    <span class=\"hljs-string\">\"generators\"</span>: [\n        <span class=\"hljs-string\">\"/generators\"</span>\n    ],\n    <span class=\"hljs-string\">\"form_handlers\"</span>: [\n        <span class=\"hljs-string\">\"/form_handlers\"</span>\n    ],\n    <span class=\"hljs-string\">\"step_definitions\"</span>: [\n        <span class=\"hljs-string\">\"/step_definitions\"</span>\n    ],\n    <span class=\"hljs-string\">\"comparators\"</span>: [\n        <span class=\"hljs-string\">\"/comparators\"</span>\n    ],\n    <span class=\"hljs-string\">\"dictionaries\"</span>: [\n        <span class=\"hljs-string\">\"/dictionaries\"</span>\n    ],\n    <span class=\"hljs-string\">\"transformers\"</span>: [\n        <span class=\"hljs-string\">\"/transformers\"</span>\n    ],\n    <span class=\"hljs-string\">\"regexes\"</span>: [\n        <span class=\"hljs-string\">\"/regexes\"</span>\n    ],\n    <span class=\"hljs-string\">\"hooks\"</span>: [\n        <span class=\"hljs-string\">\"/hooks\"</span>\n    ],\n    <span class=\"hljs-string\">\"clearEmailInboxBeforeTests\"</span>: false,\n    <span class=\"hljs-string\">\"clearCookiesAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"clearLocalStorageAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"email\"</span>: null,\n    <span class=\"hljs-string\">\"headless\"</span>: false,\n    <span class=\"hljs-string\">\"noGpu\"</span>: false,\n    <span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"otherWeb\"</span>,\n    <span class=\"hljs-string\">\"baseUrl\"</span>: <span class=\"hljs-string\">\"http://localhost:8080\"</span>,\n    <span class=\"hljs-string\">\"accounts\"</span>: {\n        <span class=\"hljs-string\">\"someAccount\"</span>: {\n            <span class=\"hljs-string\">\"accounts\"</span>: [\n                {\n                    <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n                    <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n                }\n            ]\n        }\n    }\n}\n\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration-options\"></a><a href=\"#configuration-options\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration options</h2>\n<p><code>browserWidth</code> - width of browser window <code>default: 1600</code></p>\n<p><code>browserheight</code> - height of browser window <code>default: 900</code></p>\n<p><code>timeout</code> - global timeout for a single step execution in seconds <code>default: 60</code></p>\n<p><code>maxEmailRepeats</code> - maximum email repeats to catch email used in the email step</p>\n<p><code>intervalEmail</code> - interval for email checking step <code>default: 5</code> in seconds</p>\n<p><code>elementsVisibilityTimeout</code> - maximum wait timeout for element visibility <code>default: 5</code> seconds</p>\n<p><code>waitForPageTimeout</code> - maximum wait timeout for page visibility <code>default: 5</code> seconds</p>\n<p><code>downloadTimeout</code> - maximum wait timeout for file to be downloaded <code>default: 30</code> seconds</p>\n<p><code>emails</code> - array of paths to store emails related custom code</p>\n<p><code>reports</code> - path to store reports</p>\n<p><code>downloads</code> - path to store downloaded files</p>\n<p><code>data</code> - path to store test related files (for example files to be downloaded)</p>\n<p><code>feature</code> - array of paths to store features</p>\n<p><code>pages</code> - array of paths to store page objects</p>\n<p><code>matchers</code> - array of paths to store custom matchers</p>\n<p><code>generators</code> - array of paths to store custom generators</p>\n<p><code>form_handlers</code> - array of paths to store custom form handlers</p>\n<p><code>step_definitions</code> - array of paths to store custom steps</p>\n<p><code>comparators</code> - array of paths to store custom comparators</p>\n<p><code>dictionaries</code> - array of paths to store custom dictionaries</p>\n<p><code>transformers</code> - array of paths to store custom transformers</p>\n<p><code>regexes</code> - array of paths to store custom regexes</p>\n<p><code>hooks</code> - array of paths to store custom hooks</p>\n<p><code>clearEmailInboxBeforeTests</code> - flag to active clearing email inbox before tests are executed <code>default: false | true for apps with email checking functionality activated</code></p>\n<p><code>clearCookiesAfterScenario</code> - flag to activate clearing cookies after every scenario <code>default: true</code></p>\n<p><code>clearLocalStorageAfterScenario</code> - flag to activate clearing local storage after every scenario <code>default: true</code></p>\n<p><code>email</code> - email configuration <code>default: null</code></p>\n<p>for mailtrap email checking system:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"mailtrap\"</span>,\n<span class=\"hljs-string\">\"config\"</span>: {\n    <span class=\"hljs-string\">\"apiKey\"</span>: <span class=\"hljs-string\">\"your-mailtrap-api-key\"</span>,\n    <span class=\"hljs-string\">\"inboxId\"</span>: <span class=\"hljs-string\">\"your-mailtrap-inbox\"</span>,\n    <span class=\"hljs-string\">\"url\"</span>: <span class=\"hljs-string\">\"https://mailtrap.io/api/v1\"</span>\n}\n</code></pre>\n<p>for custom email checking system only type is required:</p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"custom-type\"</span>\n</code></pre>\n<p><code>headless</code> - flag to activate chrome headless browser <code>default: false</code></p>\n<p><code>noGpu</code> - flag to activate cpu only mode <code>default: false</code></p>\n<p><code>type</code> - type of application either <code>ng1 | ng2 | otherWeb</code></p>\n<p><code>baseUrl</code> - url of tested application</p>\n<p><code>accounts</code> - object to store accounts information. This is bound to <code>userProvider</code> and allows to use advanced email checking options like recipient checking.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"someAccount\"</span>: {\n    <span class=\"hljs-string\">\"accounts\"</span>: [\n        {\n            <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n            <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n        }\n    ]\n}\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"environment-variables\"></a><a href=\"#environment-variables\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Environment variables</h2>\n<p>Kakunin uses a single <code>.env</code> file to load ENV variables. By default there is only one:</p>\n<p><code>FIXTURES_RELOAD_HOST</code> - allows you to specify host for fixtures reloading. This allows you to use <code>@reloadFixtures</code> tag on scenarios that should restore database to starting state, before the test is running</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/index\"><span class=\"arrow-prev\">← </span><span>Getting started</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/how-it-works\"><span>How it works</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#kakunin-config\">Kakunin config</a></li><li><a href=\"#configuration-options\">Configuration options</a></li><li><a href=\"#environment-variables\">Environment variables</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/configuration.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Configuration · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## Kakunin config\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Configuration · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## Kakunin config\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Configuration</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"kakunin-config\"></a><a href=\"#kakunin-config\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Kakunin config</h2>\n<pre><code class=\"hljs\">module.exports = {\n    <span class=\"hljs-string\">\"browserWidth\"</span>: <span class=\"hljs-number\">1600</span>,\n    <span class=\"hljs-string\">\"browserHeight\"</span>: <span class=\"hljs-number\">900</span>,\n    <span class=\"hljs-string\">\"timeout\"</span>: <span class=\"hljs-number\">60</span>,\n    <span class=\"hljs-string\">\"maxEmailRepeats\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"intervalEmail\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"elementsVisibilityTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"waitForPageTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"downloadTimeout\"</span>: <span class=\"hljs-number\">30</span>,\n    <span class=\"hljs-string\">\"reports\"</span>: <span class=\"hljs-string\">\"/reports\"</span>,\n    <span class=\"hljs-string\">\"downloads\"</span>: <span class=\"hljs-string\">\"/downloads\"</span>,\n    <span class=\"hljs-string\">\"data\"</span>: <span class=\"hljs-string\">\"/data\"</span>,\n    <span class=\"hljs-string\">\"features\"</span>: [\n        <span class=\"hljs-string\">\"/features\"</span>\n    ],\n    <span class=\"hljs-string\">\"pages\"</span>: [\n        <span class=\"hljs-string\">\"/pages\"</span>\n    ],\n    <span class=\"hljs-string\">\"matchers\"</span>: [\n        <span class=\"hljs-string\">\"/matchers\"</span>\n    ],\n    <span class=\"hljs-string\">\"generators\"</span>: [\n        <span class=\"hljs-string\">\"/generators\"</span>\n    ],\n    <span class=\"hljs-string\">\"form_handlers\"</span>: [\n        <span class=\"hljs-string\">\"/form_handlers\"</span>\n    ],\n    <span class=\"hljs-string\">\"step_definitions\"</span>: [\n        <span class=\"hljs-string\">\"/step_definitions\"</span>\n    ],\n    <span class=\"hljs-string\">\"comparators\"</span>: [\n        <span class=\"hljs-string\">\"/comparators\"</span>\n    ],\n    <span class=\"hljs-string\">\"dictionaries\"</span>: [\n        <span class=\"hljs-string\">\"/dictionaries\"</span>\n    ],\n    <span class=\"hljs-string\">\"transformers\"</span>: [\n        <span class=\"hljs-string\">\"/transformers\"</span>\n    ],\n    <span class=\"hljs-string\">\"regexes\"</span>: [\n        <span class=\"hljs-string\">\"/regexes\"</span>\n    ],\n    <span class=\"hljs-string\">\"hooks\"</span>: [\n        <span class=\"hljs-string\">\"/hooks\"</span>\n    ],\n    <span class=\"hljs-string\">\"clearEmailInboxBeforeTests\"</span>: false,\n    <span class=\"hljs-string\">\"clearCookiesAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"clearLocalStorageAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"email\"</span>: null,\n    <span class=\"hljs-string\">\"headless\"</span>: false,\n    <span class=\"hljs-string\">\"noGpu\"</span>: false,\n    <span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"otherWeb\"</span>,\n    <span class=\"hljs-string\">\"baseUrl\"</span>: <span class=\"hljs-string\">\"http://localhost:8080\"</span>,\n    <span class=\"hljs-string\">\"accounts\"</span>: {\n        <span class=\"hljs-string\">\"someAccount\"</span>: {\n            <span class=\"hljs-string\">\"accounts\"</span>: [\n                {\n                    <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n                    <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n                }\n            ]\n        }\n    }\n}\n\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration-options\"></a><a href=\"#configuration-options\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration options</h2>\n<p><code>browserWidth</code> - width of browser window <code>default: 1600</code></p>\n<p><code>browserheight</code> - height of browser window <code>default: 900</code></p>\n<p><code>timeout</code> - global timeout for a single step execution in seconds <code>default: 60</code></p>\n<p><code>maxEmailRepeats</code> - maximum email repeats to catch email used in the email step</p>\n<p><code>intervalEmail</code> - interval for email checking step <code>default: 5</code> in seconds</p>\n<p><code>elementsVisibilityTimeout</code> - maximum wait timeout for element visibility <code>default: 5</code> seconds</p>\n<p><code>waitForPageTimeout</code> - maximum wait timeout for page visibility <code>default: 5</code> seconds</p>\n<p><code>downloadTimeout</code> - maximum wait timeout for file to be downloaded <code>default: 30</code> seconds</p>\n<p><code>emails</code> - array of paths to store emails related custom code</p>\n<p><code>reports</code> - path to store reports</p>\n<p><code>downloads</code> - path to store downloaded files</p>\n<p><code>data</code> - path to store test related files (for example files to be downloaded)</p>\n<p><code>feature</code> - array of paths to store features</p>\n<p><code>pages</code> - array of paths to store page objects</p>\n<p><code>matchers</code> - array of paths to store custom matchers</p>\n<p><code>generators</code> - array of paths to store custom generators</p>\n<p><code>form_handlers</code> - array of paths to store custom form handlers</p>\n<p><code>step_definitions</code> - array of paths to store custom steps</p>\n<p><code>comparators</code> - array of paths to store custom comparators</p>\n<p><code>dictionaries</code> - array of paths to store custom dictionaries</p>\n<p><code>transformers</code> - array of paths to store custom transformers</p>\n<p><code>regexes</code> - array of paths to store custom regexes</p>\n<p><code>hooks</code> - array of paths to store custom hooks</p>\n<p><code>clearEmailInboxBeforeTests</code> - flag to active clearing email inbox before tests are executed <code>default: false | true for apps with email checking functionality activated</code></p>\n<p><code>clearCookiesAfterScenario</code> - flag to activate clearing cookies after every scenario <code>default: true</code></p>\n<p><code>clearLocalStorageAfterScenario</code> - flag to activate clearing local storage after every scenario <code>default: true</code></p>\n<p><code>email</code> - email configuration <code>default: null</code></p>\n<p>for mailtrap email checking system:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"mailtrap\"</span>,\n<span class=\"hljs-string\">\"config\"</span>: {\n    <span class=\"hljs-string\">\"apiKey\"</span>: <span class=\"hljs-string\">\"your-mailtrap-api-key\"</span>,\n    <span class=\"hljs-string\">\"inboxId\"</span>: <span class=\"hljs-string\">\"your-mailtrap-inbox\"</span>,\n    <span class=\"hljs-string\">\"url\"</span>: <span class=\"hljs-string\">\"https://mailtrap.io/api/v1\"</span>\n}\n</code></pre>\n<p>for custom email checking system only type is required:</p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"custom-type\"</span>\n</code></pre>\n<p><code>headless</code> - flag to activate chrome headless browser <code>default: false</code></p>\n<p><code>noGpu</code> - flag to activate cpu only mode <code>default: false</code></p>\n<p><code>type</code> - type of application either <code>ng1 | ng2 | otherWeb</code></p>\n<p><code>baseUrl</code> - url of tested application</p>\n<p><code>accounts</code> - object to store accounts information. This is bound to <code>userProvider</code> and allows to use advanced email checking options like recipient checking.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"someAccount\"</span>: {\n    <span class=\"hljs-string\">\"accounts\"</span>: [\n        {\n            <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n            <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n        }\n    ]\n}\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"environment-variables\"></a><a href=\"#environment-variables\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Environment variables</h2>\n<p>Kakunin uses a single <code>.env</code> file to load ENV variables. By default there is only one:</p>\n<p><code>FIXTURES_RELOAD_HOST</code> - allows you to specify host for fixtures reloading. This allows you to use <code>@reloadFixtures</code> tag on scenarios that should restore database to starting state, before the test is running</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/index\"><span class=\"arrow-prev\">← </span><span>Getting started</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/how-it-works\"><span>How it works</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#kakunin-config\">Kakunin config</a></li><li><a href=\"#configuration-options\">Configuration options</a></li><li><a href=\"#environment-variables\">Environment variables</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/cross-browser/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Cross-browser testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## To run tests with specified browser\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Cross-browser testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## To run tests with specified browser\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Cross-browser testing</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-with-specified-browser\"></a><a href=\"#to-run-tests-with-specified-browser\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests with specified browser</h2>\n<p>There is a possibility to run Kakunin in various browsers:</p>\n<ul>\n<li>Google Chrome (by default) <code>npm run kakunin</code> or <code>npm run kakunin -- --chrome</code></li>\n<li>Firefox <code>npm run kakunin -- --firefox</code></li>\n<li>Safari <code>npm run kakunin -- --safari</code></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-in-different-browsers-at-once\"></a><a href=\"#to-run-tests-in-different-browsers-at-once\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests in different browsers at once</h2>\n<p>There is a possibility to run more than one instance of WebDriver by giving an extra parameter to a command line:</p>\n<ul>\n<li><code>npm run kakunin --chrome --firefox</code></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"safari\"></a><a href=\"#safari\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Safari</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h3>\n<ol>\n<li>Open Safari's preferences</li>\n<li>Enable &quot;Show Develop menu in menu bar&quot;</li>\n<li>Open &quot;Develop&quot; tab</li>\n<li>Enable &quot;Allow Remote Automation&quot;</li>\n</ol>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h3>\n<p>Safari version 12.0:</p>\n<ul>\n<li>drag &amp; drop actions in Kakunin impossible (more details <a href=\"https://github.com/angular/protractor/issues/1526\">https://github.com/angular/protractor/issues/1526</a>)</li>\n</ul>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/extending\"><span class=\"arrow-prev\">← </span><span>Extending Kakunin</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/parallel-testing\"><span>Parallel testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#to-run-tests-with-specified-browser\">To run tests with specified browser</a></li><li><a href=\"#to-run-tests-in-different-browsers-at-once\">To run tests in different browsers at once</a></li><li><a href=\"#safari\">Safari</a><ul class=\"toc-headings\"><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/cross-browser.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Cross-browser testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## To run tests with specified browser\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Cross-browser testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## To run tests with specified browser\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Cross-browser testing</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-with-specified-browser\"></a><a href=\"#to-run-tests-with-specified-browser\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests with specified browser</h2>\n<p>There is a possibility to run Kakunin in various browsers:</p>\n<ul>\n<li>Google Chrome (by default) <code>npm run kakunin</code> or <code>npm run kakunin -- --chrome</code></li>\n<li>Firefox <code>npm run kakunin -- --firefox</code></li>\n<li>Safari <code>npm run kakunin -- --safari</code></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-in-different-browsers-at-once\"></a><a href=\"#to-run-tests-in-different-browsers-at-once\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests in different browsers at once</h2>\n<p>There is a possibility to run more than one instance of WebDriver by giving an extra parameter to a command line:</p>\n<ul>\n<li><code>npm run kakunin --chrome --firefox</code></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"safari\"></a><a href=\"#safari\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Safari</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h3>\n<ol>\n<li>Open Safari's preferences</li>\n<li>Enable &quot;Show Develop menu in menu bar&quot;</li>\n<li>Open &quot;Develop&quot; tab</li>\n<li>Enable &quot;Allow Remote Automation&quot;</li>\n</ol>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h3>\n<p>Safari version 12.0:</p>\n<ul>\n<li>drag &amp; drop actions in Kakunin impossible (more details <a href=\"https://github.com/angular/protractor/issues/1526\">https://github.com/angular/protractor/issues/1526</a>)</li>\n</ul>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/extending\"><span class=\"arrow-prev\">← </span><span>Extending Kakunin</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/parallel-testing\"><span>Parallel testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#to-run-tests-with-specified-browser\">To run tests with specified browser</a></li><li><a href=\"#to-run-tests-in-different-browsers-at-once\">To run tests in different browsers at once</a></li><li><a href=\"#safari\">Safari</a><ul class=\"toc-headings\"><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/docker/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Docker · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Docker for Kakunin tests\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Docker · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Docker for Kakunin tests\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Docker</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"docker-for-kakunin-tests\"></a><a href=\"#docker-for-kakunin-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Docker for Kakunin tests</h1>\n<p>This section explains how to run kakunin tests inside docker, below examples of Dockerfile\nand docker-compose.yml files let you build your first docker image and run tests.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dockerfile\"></a><a href=\"#dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dockerfile:</h2>\n<p>This file is responsible for building the whole environment for our e2e tests.\nIt will allow you to run tests on local and CI environments,\nby configuring and copying the whole project inside the container.\nJust simply place it inside your e2e project root.</p>\n<p>Below an example of Dockerfile</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-dockerfile\"></a><a href=\"#example-of-dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of Dockerfile:</h3>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-comment\"># Downloading selenium image and setting privileges</span>\nFROM selenium/standalone-chrome:3.14.0\nUSER root\n<span class=\"hljs-comment\"># Setting test directory</span>\nWORKDIR /app\n<span class=\"hljs-comment\"># Install openjdk-8-jdk-headless</span>\nRUN apt-get update -qqy \\\n  &amp;&amp; apt-get -qqy --no-install-recommends install \\\n    xvfb \\\n    openjdk-8-jdk-headless \\\n    curl \\\n    make \\\n  &amp;&amp; rm -rf /var/lib/apt/lists/* /var/cache/apt/*\n<span class=\"hljs-comment\"># Installing node 8 globally and setting paths</span>\nRUN <span class=\"hljs-built_in\">set</span> -x \\\n    &amp;&amp; curl -sL https://deb.nodesource.com/setup_8.x | bash - \\\n    &amp;&amp; apt-get install -y \\\n        nodejs \\\n    &amp;&amp; npm install -g npm@latest\nRUN PATH=/usr/bin/node:<span class=\"hljs-variable\">$PATH</span>\n<span class=\"hljs-comment\"># Copy tests directory with ignored files from .dockerignore</span>\nCOPY --chown=seluser:seluser . .\n<span class=\"hljs-comment\"># Removing node_modules in case of existence or lack of .dockerignore and installing from package.json</span>\nRUN rm -rf ./node_modules \\\n    &amp;&amp; npm install\n<span class=\"hljs-comment\"># Setting Xvfb</span>\nRUN <span class=\"hljs-built_in\">export</span> DISPLAY=:99.0\nUSER seluser\n</code></pre>\n<p>##docker-compose.yml</p>\n<p>Compose is a tool for defining and running multi-container Docker applications, which we use\nfor running our tests.</p>\n<p>Running command: <code>docker-compose up -d</code> will start Dockerfile script, as a result, it builds the container.</p>\n<p>Running command: <code>docker-compose build</code> or <code>docker-compose up --build</code> will\nrebuild container, if there were made any changes.</p>\n<p>Running command: <code>docker-compose run --rm e2e</code> will start running tests inside the container</p>\n<p>Composition below allows you to run e2e tests inside the container and configure it locally or\nin CI environments.</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-docker-composeyml\"></a><a href=\"#example-of-docker-composeyml\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of docker-compose.yml:</h3>\n<pre><code class=\"hljs css language-bash\">e2e:\n      build: .\n      working_dir: /app\n      <span class=\"hljs-built_in\">command</span>: sh -c <span class=\"hljs-string\">\"Xvfb -ac :99 -screen 0 1280x1024x16 &amp; npm run kakunin\"</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-run-step-by-step\"></a><a href=\"#how-to-run-step-by-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to run step by step</h3>\n<ol>\n<li>Install docker (e.g Docker for Mac),</li>\n<li>Create Dockerfile and docker-compose.yml in the root of your e2e project,</li>\n<li>Run in command line <code>docker-compose up -d</code> which will start docker and build image\nif it's not build</li>\n<li>Run in command line <code>docker-compose run --rm e2e</code> to run your tests</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/performance-testing\"><span class=\"arrow-prev\">← </span><span>Performance testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-navigation\"><span>Navigation</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dockerfile\">Dockerfile:</a><ul class=\"toc-headings\"><li><a href=\"#example-of-dockerfile\">Example of Dockerfile:</a></li><li><a href=\"#example-of-docker-composeyml\">Example of docker-compose.yml:</a></li><li><a href=\"#how-to-run-step-by-step\">How to run step by step</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/docker.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Docker · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Docker for Kakunin tests\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Docker · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Docker for Kakunin tests\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Docker</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"docker-for-kakunin-tests\"></a><a href=\"#docker-for-kakunin-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Docker for Kakunin tests</h1>\n<p>This section explains how to run kakunin tests inside docker, below examples of Dockerfile\nand docker-compose.yml files let you build your first docker image and run tests.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dockerfile\"></a><a href=\"#dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dockerfile:</h2>\n<p>This file is responsible for building the whole environment for our e2e tests.\nIt will allow you to run tests on local and CI environments,\nby configuring and copying the whole project inside the container.\nJust simply place it inside your e2e project root.</p>\n<p>Below an example of Dockerfile</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-dockerfile\"></a><a href=\"#example-of-dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of Dockerfile:</h3>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-comment\"># Downloading selenium image and setting privileges</span>\nFROM selenium/standalone-chrome:3.14.0\nUSER root\n<span class=\"hljs-comment\"># Setting test directory</span>\nWORKDIR /app\n<span class=\"hljs-comment\"># Install openjdk-8-jdk-headless</span>\nRUN apt-get update -qqy \\\n  &amp;&amp; apt-get -qqy --no-install-recommends install \\\n    xvfb \\\n    openjdk-8-jdk-headless \\\n    curl \\\n    make \\\n  &amp;&amp; rm -rf /var/lib/apt/lists/* /var/cache/apt/*\n<span class=\"hljs-comment\"># Installing node 8 globally and setting paths</span>\nRUN <span class=\"hljs-built_in\">set</span> -x \\\n    &amp;&amp; curl -sL https://deb.nodesource.com/setup_8.x | bash - \\\n    &amp;&amp; apt-get install -y \\\n        nodejs \\\n    &amp;&amp; npm install -g npm@latest\nRUN PATH=/usr/bin/node:<span class=\"hljs-variable\">$PATH</span>\n<span class=\"hljs-comment\"># Copy tests directory with ignored files from .dockerignore</span>\nCOPY --chown=seluser:seluser . .\n<span class=\"hljs-comment\"># Removing node_modules in case of existence or lack of .dockerignore and installing from package.json</span>\nRUN rm -rf ./node_modules \\\n    &amp;&amp; npm install\n<span class=\"hljs-comment\"># Setting Xvfb</span>\nRUN <span class=\"hljs-built_in\">export</span> DISPLAY=:99.0\nUSER seluser\n</code></pre>\n<p>##docker-compose.yml</p>\n<p>Compose is a tool for defining and running multi-container Docker applications, which we use\nfor running our tests.</p>\n<p>Running command: <code>docker-compose up -d</code> will start Dockerfile script, as a result, it builds the container.</p>\n<p>Running command: <code>docker-compose build</code> or <code>docker-compose up --build</code> will\nrebuild container, if there were made any changes.</p>\n<p>Running command: <code>docker-compose run --rm e2e</code> will start running tests inside the container</p>\n<p>Composition below allows you to run e2e tests inside the container and configure it locally or\nin CI environments.</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-docker-composeyml\"></a><a href=\"#example-of-docker-composeyml\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of docker-compose.yml:</h3>\n<pre><code class=\"hljs css language-bash\">e2e:\n      build: .\n      working_dir: /app\n      <span class=\"hljs-built_in\">command</span>: sh -c <span class=\"hljs-string\">\"Xvfb -ac :99 -screen 0 1280x1024x16 &amp; npm run kakunin\"</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-run-step-by-step\"></a><a href=\"#how-to-run-step-by-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to run step by step</h3>\n<ol>\n<li>Install docker (e.g Docker for Mac),</li>\n<li>Create Dockerfile and docker-compose.yml in the root of your e2e project,</li>\n<li>Run in command line <code>docker-compose up -d</code> which will start docker and build image\nif it's not build</li>\n<li>Run in command line <code>docker-compose run --rm e2e</code> to run your tests</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/performance-testing\"><span class=\"arrow-prev\">← </span><span>Performance testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-navigation\"><span>Navigation</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dockerfile\">Dockerfile:</a><ul class=\"toc-headings\"><li><a href=\"#example-of-dockerfile\">Example of Dockerfile:</a></li><li><a href=\"#example-of-docker-composeyml\">Example of docker-compose.yml:</a></li><li><a href=\"#how-to-run-step-by-step\">How to run step by step</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/extending/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Extending Kakunin · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Extending Kakunin · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Extending Kakunin</h1></header><article><div><span><p>Kakunin allows you to easily add a custom code in order to extend it's functionality.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"internal-services\"></a><a href=\"#internal-services\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Internal services</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-builder\"></a><a href=\"#regex-builder\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex builder</h3>\n<p>Regex builder is a special builder for creating <code>RegExp</code> objects based on regexp name. Internally it has access to not only to all built-in\nregular expression files, but also custom ones specified by user.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { regexBuilder } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> myRegex = regexBuilder.buildRegex(<span class=\"hljs-string\">'r:number'</span>);\n\n<span class=\"hljs-comment\">//myRegex will contain RegExp object that matches regular expression under the name \"number\" in regexes file.</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h3>\n<p>Variable store allows you to store and read some values to be used during given scenario.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { variableStore } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\nvariableStore.storeVariable(<span class=\"hljs-string\">'some-name'</span>, <span class=\"hljs-string\">'some-value'</span>);\n\n<span class=\"hljs-keyword\">const</span> myValue = variableStore.getVariableValue(<span class=\"hljs-string\">'some-name'</span>); <span class=\"hljs-comment\">//contains 'some-value'</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"user-provider\"></a><a href=\"#user-provider\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User provider</h3>\n<p>Kakunin comes with functionality that allows you to easily load credentials for a given account type - <code>UserProvider</code>.</p>\n<p>In <code>kakunin.conf.js</code> you can find a section <code>accounts</code>.</p>\n<p>The structure it has is very simple:</p>\n<pre><code class=\"hljs css language-json\">\"accounts\": {\n    \"someAccount\": {\n        \"accounts\": [\n            {\n                \"email\": \"\",\n                \"password\": \"\"\n            }\n        ]\n    }\n}\n</code></pre>\n<p><code>someAccount</code> - the name of accounts group</p>\n<p><code>accounts</code> - an array of account credentials (in order to be able to check if a <code>currentUser</code> got an email, this has to have an <code>email</code> key, otherwise account can have any kind of\nproperties)</p>\n<p>Use provider is accessible inside any kind of a step by calling <code>this.userProvider</code>. It comes with a single method:</p>\n<p><code>this.userProvider.getUser(groupName)</code> - returns an account credentials for a given user group.</p>\n<p>It is a good practice to save a current user in <code>this.currentUser</code> variable for a email checking service.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"adding-custom-code\"></a><a href=\"#adding-custom-code\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding custom code</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"custom-step\"></a><a href=\"#custom-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Custom step</h3>\n<p>In order to add a custom step, you have to create inside of a directory specified as <code>step_definitions</code> in kakunin configuration file <code>default: /step_definitions</code>.</p>\n<p>We're using <code>cucumber-js 4.X</code> so in order to add custom step you have to use <code>defineSupportCode</code> method like this:</p>\n<pre><code class=\"hljs css language-javascript\">  <span class=\"hljs-keyword\">const</span> { defineSupportCode } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n  \n  defineSupportCode(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ When }</span>) =&gt;</span> {\n    When(<span class=\"hljs-regexp\">/^I use kakunin$/</span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) </span>{\n      expect(<span class=\"hljs-literal\">true</span>).to.equal(<span class=\"hljs-literal\">true</span>);\n    });\n  });\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h3>\n<p>Kakunin comes with some built-in page objects, that should be used as a base for your page objects.</p>\n<p>In order to create a custom one, create a file inside the <code>pages</code> directory and extend the <code>BasePage</code> from kakunin package.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyPageObject</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.myElement = element(by.css(<span class=\"hljs-string\">'.some-elemnt'</span>));\n  }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MyPageObject;\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"matchers\"></a><a href=\"#matchers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Matchers</h3>\n<p>Matchers are used to compare if given value is matching our expectation. For example if a value in table is a number.</p>\n<p>You can add your own matcher as below:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { matchers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyMatcher</span> </span>{\n  isSatisfiedBy(prefix, name) {\n    <span class=\"hljs-keyword\">return</span> prefix === <span class=\"hljs-string\">'m:'</span> &amp;&amp; name === <span class=\"hljs-string\">'pending'</span>;\n  }\n \n  match(protractorElement, matcherName) {\n    <span class=\"hljs-keyword\">return</span> protractorElement.getText().then(<span class=\"hljs-function\">(<span class=\"hljs-params\">value</span>) =&gt;</span> {\n      <span class=\"hljs-keyword\">if</span> (value === <span class=\"hljs-string\">'pending'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n      }\n      \n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Matcher \"MyMatcher\" could not match value on element \"<span class=\"hljs-subst\">${protractorElement.locator()}</span>\". Expected: \"pending\", given: \"<span class=\"hljs-subst\">${value}</span>\"`</span>);\n    }); \n  }\n}\n\nmatchers.addMatcher(<span class=\"hljs-keyword\">new</span> MyMatcher());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h3>\n<p>Dictionaries allows you to present complicated values in much more readable way. For example if an element must be\nin a form of IRI <code>/some-resource/123-123-123-23</code> and you wish to use <code>pending-resource</code> as it's alias.</p>\n<p>You can add your own dictionary:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { dictionaries } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n<span class=\"hljs-keyword\">const</span> { BaseDictionary } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">TestDictionary</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BaseDictionary</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">super</span>(<span class=\"hljs-string\">'name-of-dictionary'</span>, {\n      <span class=\"hljs-string\">'pending-resource'</span>: <span class=\"hljs-string\">'/some-resource/123-123-123-23'</span>,\n      <span class=\"hljs-string\">'test-value'</span>: <span class=\"hljs-string\">'some other value'</span>\n    });\n  }\n}\n\ndictionaries.addDictionary(<span class=\"hljs-keyword\">new</span> TestDictionary());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h3>\n<p>Generators allows you to create random values</p>\n<p>You can add your own generator:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { generators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyGeneerator</span></span>{\n  isSatisfiedBy(name) {\n    <span class=\"hljs-keyword\">return</span> name === <span class=\"hljs-string\">'my-generator'</span>;\n  }\n\n  generate(params) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'some-random-value'</span>);\n  }\n}\n\ngenerators.addGenerator(<span class=\"hljs-keyword\">new</span> MyGeneerator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"comparators\"></a><a href=\"#comparators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Comparators</h3>\n<p>Comparators allows you to check if a set of values has an expected order</p>\n<p>You can add your own comparators:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { comparators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyComparator</span> </span>{\n  isSatisfiedBy(values) {\n    <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">let</span> i=<span class=\"hljs-number\">0</span>; i&lt;values.length; i++) {\n      <span class=\"hljs-keyword\">if</span> (values[i] !== <span class=\"hljs-string\">'foo'</span> &amp;&amp; values[i] !== <span class=\"hljs-string\">'bar'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n  }\n  \n  compare(values, order) {\n    <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">let</span> i = <span class=\"hljs-number\">1</span>; i &lt; values.length; i++) {\n      <span class=\"hljs-keyword\">const</span> previousValue = values[i - <span class=\"hljs-number\">1</span>];\n      <span class=\"hljs-keyword\">const</span> currentValue = values[i];\n\n      <span class=\"hljs-keyword\">if</span> (previousValue === currentValue) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">'Wrong order'</span>);\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'Foo bar!'</span>);\n  }\n};\n\ncomparators.addComparator(<span class=\"hljs-keyword\">new</span> MyComparator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"form-handlers\"></a><a href=\"#form-handlers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Form handlers</h3>\n<p>Form handlers allows you to fill the form inputs and check value of filled fields</p>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { handlers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> MyHandler {\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.registerFieldType = <span class=\"hljs-literal\">false</span>;\n    <span class=\"hljs-keyword\">this</span>.fieldType = <span class=\"hljs-string\">'default'</span>;\n  }\n\n  isSatisfiedBy(element, elementName) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(elementName === <span class=\"hljs-string\">'someElementName'</span>);\n  }\n \n  handleFill(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].clear().then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n          <span class=\"hljs-keyword\">return</span> page[elementName].sendKeys(desiredValue);\n        });\n      }\n    );\n  }\n\n  handleCheck(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].getAttribute(<span class=\"hljs-string\">'value'</span>).then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">value</span>) </span>{\n          <span class=\"hljs-keyword\">if</span> (value === desiredValue) {\n            <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve();\n          }\n\n          <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Expected <span class=\"hljs-subst\">${desiredValue}</span> got <span class=\"hljs-subst\">${value}</span> for text input element <span class=\"hljs-subst\">${elementName}</span>`</span>);\n        });\n      }\n    );\n  }\n};\n\nhandlers.addHandler(<span class=\"hljs-keyword\">new</span> MyHandler());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"transformers\"></a><a href=\"#transformers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Transformers</h3>\n<p>Transformers can be used in steps <code>When I fill the &quot;form&quot; form with:</code> and <code>And the &quot;joinOurStoreForm&quot; form is filled with:</code>.</p>\n<p>Existing transformers:</p>\n<ul>\n<li>generators (prefix: <code>g:</code>)</li>\n<li>dictionaries (prefix: <code>d:</code>)</li>\n<li>variableStore (prefix: <code>v:</code>)\nTransformers can be used in mentioned steps by using specific 'prefix', parameters are sent after <code>:</code> sign.\nExample:\n<code>g:generatorName:param:param</code></li>\n</ul>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { transformers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyTransformer</span> </span>{\n\n  isSatisfiedBy(prefix) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-string\">'yourPrefix:'</span> === prefix;\n  }\n\n  transform(value) {\n    <span class=\"hljs-comment\">//code</span>\n  }\n}\ntransformers.addTransformer(<span class=\"hljs-keyword\">new</span> MyTransformer());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"email-checking-service\"></a><a href=\"#email-checking-service\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Email checking service</h3>\n<p>You can easily check emails with Kakunin. By default we give you MailTrap client implementation, but you can easily add your own client.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { emailService } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyEmailService</span> </span>{\n  <span class=\"hljs-comment\">//you have access to full kakunin config</span>\n  isSatisfiedBy(config) {\n    <span class=\"hljs-keyword\">return</span> config.email.type === <span class=\"hljs-string\">'my-custom-email-service'</span>;\n  }\n  \n  <span class=\"hljs-comment\">//method used to clear emails before tests</span>\n  clearInbox() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to get emails - this method should return emails in format described below</span>\n  getEmails() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to retrive atachments for given email - should return attachments in format described below</span>\n  getAttachments(email) {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to mark given email as read</span>\n  markAsRead(email) {\n    ...\n  }\n}\n\nemailService.addAdapter(<span class=\"hljs-keyword\">new</span> MyEmailService());\n</code></pre>\n<p>Emails should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"subject\"</span>: <span class=\"hljs-string\">\"SMTP e-mail test\"</span>,\n      <span class=\"hljs-string\">\"sent_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.567+03:00\"</span>,\n      <span class=\"hljs-string\">\"from_email\"</span>: <span class=\"hljs-string\">\"me@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"from_name\"</span>: <span class=\"hljs-string\">\"Private Person\"</span>,\n      <span class=\"hljs-string\">\"to_email\"</span>: <span class=\"hljs-string\">\"test@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"to_name\"</span>: <span class=\"hljs-string\">\"A Test User\"</span>,\n      <span class=\"hljs-string\">\"html_body\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"text_body\"</span>: <span class=\"hljs-string\">\"This is a test e-mail message.\\r\\n\"</span>,\n      <span class=\"hljs-string\">\"email_size\"</span>: <span class=\"hljs-number\">193</span>,\n      <span class=\"hljs-string\">\"is_read\"</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.576+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:09.232+03:00\"</span>,\n      <span class=\"hljs-string\">\"sent_at_timestamp\"</span>: <span class=\"hljs-number\">1377448326</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap email format.</p>\n<p>Attachments should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"id\"</span>: <span class=\"hljs-number\">1737</span>,\n      <span class=\"hljs-string\">\"message_id\"</span>: <span class=\"hljs-number\">54508</span>,\n      <span class=\"hljs-string\">\"filename\"</span>: <span class=\"hljs-string\">\"Photos.png\"</span>,\n      <span class=\"hljs-string\">\"attachment_type\"</span>: <span class=\"hljs-string\">\"attachment\"</span>,\n      <span class=\"hljs-string\">\"content_type\"</span>: <span class=\"hljs-string\">\"image/png\"</span>,\n      <span class=\"hljs-string\">\"content_id\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"transfer_encoding\"</span>: <span class=\"hljs-string\">\"base64\"</span>,\n      <span class=\"hljs-string\">\"attachment_size\"</span>: <span class=\"hljs-number\">213855</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"attachment_human_size\"</span>: <span class=\"hljs-string\">\"210 KB\"</span>,\n      <span class=\"hljs-string\">\"download_path\"</span>: <span class=\"hljs-string\">\"/api/v1/inboxes/3/messages/54508/attachments/1737/download\"</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap attachment format.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/transformers\"><span class=\"arrow-prev\">← </span><span>Transformers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/cross-browser\"><span>Cross-browser testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#internal-services\">Internal services</a><ul class=\"toc-headings\"><li><a href=\"#regex-builder\">Regex builder</a></li><li><a href=\"#variable-store\">Variable store</a></li><li><a href=\"#user-provider\">User provider</a></li></ul></li><li><a href=\"#adding-custom-code\">Adding custom code</a><ul class=\"toc-headings\"><li><a href=\"#custom-step\">Custom step</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#matchers\">Matchers</a></li><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#comparators\">Comparators</a></li><li><a href=\"#form-handlers\">Form handlers</a></li><li><a href=\"#transformers\">Transformers</a></li><li><a href=\"#email-checking-service\">Email checking service</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/extending.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Extending Kakunin · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Extending Kakunin · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Extending Kakunin</h1></header><article><div><span><p>Kakunin allows you to easily add a custom code in order to extend it's functionality.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"internal-services\"></a><a href=\"#internal-services\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Internal services</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-builder\"></a><a href=\"#regex-builder\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex builder</h3>\n<p>Regex builder is a special builder for creating <code>RegExp</code> objects based on regexp name. Internally it has access to not only to all built-in\nregular expression files, but also custom ones specified by user.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { regexBuilder } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> myRegex = regexBuilder.buildRegex(<span class=\"hljs-string\">'r:number'</span>);\n\n<span class=\"hljs-comment\">//myRegex will contain RegExp object that matches regular expression under the name \"number\" in regexes file.</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h3>\n<p>Variable store allows you to store and read some values to be used during given scenario.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { variableStore } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\nvariableStore.storeVariable(<span class=\"hljs-string\">'some-name'</span>, <span class=\"hljs-string\">'some-value'</span>);\n\n<span class=\"hljs-keyword\">const</span> myValue = variableStore.getVariableValue(<span class=\"hljs-string\">'some-name'</span>); <span class=\"hljs-comment\">//contains 'some-value'</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"user-provider\"></a><a href=\"#user-provider\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User provider</h3>\n<p>Kakunin comes with functionality that allows you to easily load credentials for a given account type - <code>UserProvider</code>.</p>\n<p>In <code>kakunin.conf.js</code> you can find a section <code>accounts</code>.</p>\n<p>The structure it has is very simple:</p>\n<pre><code class=\"hljs css language-json\">\"accounts\": {\n    \"someAccount\": {\n        \"accounts\": [\n            {\n                \"email\": \"\",\n                \"password\": \"\"\n            }\n        ]\n    }\n}\n</code></pre>\n<p><code>someAccount</code> - the name of accounts group</p>\n<p><code>accounts</code> - an array of account credentials (in order to be able to check if a <code>currentUser</code> got an email, this has to have an <code>email</code> key, otherwise account can have any kind of\nproperties)</p>\n<p>Use provider is accessible inside any kind of a step by calling <code>this.userProvider</code>. It comes with a single method:</p>\n<p><code>this.userProvider.getUser(groupName)</code> - returns an account credentials for a given user group.</p>\n<p>It is a good practice to save a current user in <code>this.currentUser</code> variable for a email checking service.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"adding-custom-code\"></a><a href=\"#adding-custom-code\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding custom code</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"custom-step\"></a><a href=\"#custom-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Custom step</h3>\n<p>In order to add a custom step, you have to create inside of a directory specified as <code>step_definitions</code> in kakunin configuration file <code>default: /step_definitions</code>.</p>\n<p>We're using <code>cucumber-js 4.X</code> so in order to add custom step you have to use <code>defineSupportCode</code> method like this:</p>\n<pre><code class=\"hljs css language-javascript\">  <span class=\"hljs-keyword\">const</span> { defineSupportCode } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n  \n  defineSupportCode(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ When }</span>) =&gt;</span> {\n    When(<span class=\"hljs-regexp\">/^I use kakunin$/</span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) </span>{\n      expect(<span class=\"hljs-literal\">true</span>).to.equal(<span class=\"hljs-literal\">true</span>);\n    });\n  });\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h3>\n<p>Kakunin comes with some built-in page objects, that should be used as a base for your page objects.</p>\n<p>In order to create a custom one, create a file inside the <code>pages</code> directory and extend the <code>BasePage</code> from kakunin package.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyPageObject</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.myElement = element(by.css(<span class=\"hljs-string\">'.some-elemnt'</span>));\n  }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MyPageObject;\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"matchers\"></a><a href=\"#matchers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Matchers</h3>\n<p>Matchers are used to compare if given value is matching our expectation. For example if a value in table is a number.</p>\n<p>You can add your own matcher as below:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { matchers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyMatcher</span> </span>{\n  isSatisfiedBy(prefix, name) {\n    <span class=\"hljs-keyword\">return</span> prefix === <span class=\"hljs-string\">'m:'</span> &amp;&amp; name === <span class=\"hljs-string\">'pending'</span>;\n  }\n \n  match(protractorElement, matcherName) {\n    <span class=\"hljs-keyword\">return</span> protractorElement.getText().then(<span class=\"hljs-function\">(<span class=\"hljs-params\">value</span>) =&gt;</span> {\n      <span class=\"hljs-keyword\">if</span> (value === <span class=\"hljs-string\">'pending'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n      }\n      \n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Matcher \"MyMatcher\" could not match value on element \"<span class=\"hljs-subst\">${protractorElement.locator()}</span>\". Expected: \"pending\", given: \"<span class=\"hljs-subst\">${value}</span>\"`</span>);\n    }); \n  }\n}\n\nmatchers.addMatcher(<span class=\"hljs-keyword\">new</span> MyMatcher());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h3>\n<p>Dictionaries allows you to present complicated values in much more readable way. For example if an element must be\nin a form of IRI <code>/some-resource/123-123-123-23</code> and you wish to use <code>pending-resource</code> as it's alias.</p>\n<p>You can add your own dictionary:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { dictionaries } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n<span class=\"hljs-keyword\">const</span> { BaseDictionary } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">TestDictionary</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BaseDictionary</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">super</span>(<span class=\"hljs-string\">'name-of-dictionary'</span>, {\n      <span class=\"hljs-string\">'pending-resource'</span>: <span class=\"hljs-string\">'/some-resource/123-123-123-23'</span>,\n      <span class=\"hljs-string\">'test-value'</span>: <span class=\"hljs-string\">'some other value'</span>\n    });\n  }\n}\n\ndictionaries.addDictionary(<span class=\"hljs-keyword\">new</span> TestDictionary());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h3>\n<p>Generators allows you to create random values</p>\n<p>You can add your own generator:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { generators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyGeneerator</span></span>{\n  isSatisfiedBy(name) {\n    <span class=\"hljs-keyword\">return</span> name === <span class=\"hljs-string\">'my-generator'</span>;\n  }\n\n  generate(params) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'some-random-value'</span>);\n  }\n}\n\ngenerators.addGenerator(<span class=\"hljs-keyword\">new</span> MyGeneerator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"comparators\"></a><a href=\"#comparators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Comparators</h3>\n<p>Comparators allows you to check if a set of values has an expected order</p>\n<p>You can add your own comparators:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { comparators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyComparator</span> </span>{\n  isSatisfiedBy(values) {\n    <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">let</span> i=<span class=\"hljs-number\">0</span>; i&lt;values.length; i++) {\n      <span class=\"hljs-keyword\">if</span> (values[i] !== <span class=\"hljs-string\">'foo'</span> &amp;&amp; values[i] !== <span class=\"hljs-string\">'bar'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n  }\n  \n  compare(values, order) {\n    <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">let</span> i = <span class=\"hljs-number\">1</span>; i &lt; values.length; i++) {\n      <span class=\"hljs-keyword\">const</span> previousValue = values[i - <span class=\"hljs-number\">1</span>];\n      <span class=\"hljs-keyword\">const</span> currentValue = values[i];\n\n      <span class=\"hljs-keyword\">if</span> (previousValue === currentValue) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">'Wrong order'</span>);\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'Foo bar!'</span>);\n  }\n};\n\ncomparators.addComparator(<span class=\"hljs-keyword\">new</span> MyComparator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"form-handlers\"></a><a href=\"#form-handlers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Form handlers</h3>\n<p>Form handlers allows you to fill the form inputs and check value of filled fields</p>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { handlers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> MyHandler {\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.registerFieldType = <span class=\"hljs-literal\">false</span>;\n    <span class=\"hljs-keyword\">this</span>.fieldType = <span class=\"hljs-string\">'default'</span>;\n  }\n\n  isSatisfiedBy(element, elementName) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(elementName === <span class=\"hljs-string\">'someElementName'</span>);\n  }\n \n  handleFill(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].clear().then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n          <span class=\"hljs-keyword\">return</span> page[elementName].sendKeys(desiredValue);\n        });\n      }\n    );\n  }\n\n  handleCheck(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].getAttribute(<span class=\"hljs-string\">'value'</span>).then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">value</span>) </span>{\n          <span class=\"hljs-keyword\">if</span> (value === desiredValue) {\n            <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve();\n          }\n\n          <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Expected <span class=\"hljs-subst\">${desiredValue}</span> got <span class=\"hljs-subst\">${value}</span> for text input element <span class=\"hljs-subst\">${elementName}</span>`</span>);\n        });\n      }\n    );\n  }\n};\n\nhandlers.addHandler(<span class=\"hljs-keyword\">new</span> MyHandler());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"transformers\"></a><a href=\"#transformers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Transformers</h3>\n<p>Transformers can be used in steps <code>When I fill the &quot;form&quot; form with:</code> and <code>And the &quot;joinOurStoreForm&quot; form is filled with:</code>.</p>\n<p>Existing transformers:</p>\n<ul>\n<li>generators (prefix: <code>g:</code>)</li>\n<li>dictionaries (prefix: <code>d:</code>)</li>\n<li>variableStore (prefix: <code>v:</code>)\nTransformers can be used in mentioned steps by using specific 'prefix', parameters are sent after <code>:</code> sign.\nExample:\n<code>g:generatorName:param:param</code></li>\n</ul>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { transformers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyTransformer</span> </span>{\n\n  isSatisfiedBy(prefix) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-string\">'yourPrefix:'</span> === prefix;\n  }\n\n  transform(value) {\n    <span class=\"hljs-comment\">//code</span>\n  }\n}\ntransformers.addTransformer(<span class=\"hljs-keyword\">new</span> MyTransformer());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"email-checking-service\"></a><a href=\"#email-checking-service\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Email checking service</h3>\n<p>You can easily check emails with Kakunin. By default we give you MailTrap client implementation, but you can easily add your own client.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { emailService } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyEmailService</span> </span>{\n  <span class=\"hljs-comment\">//you have access to full kakunin config</span>\n  isSatisfiedBy(config) {\n    <span class=\"hljs-keyword\">return</span> config.email.type === <span class=\"hljs-string\">'my-custom-email-service'</span>;\n  }\n  \n  <span class=\"hljs-comment\">//method used to clear emails before tests</span>\n  clearInbox() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to get emails - this method should return emails in format described below</span>\n  getEmails() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to retrive atachments for given email - should return attachments in format described below</span>\n  getAttachments(email) {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to mark given email as read</span>\n  markAsRead(email) {\n    ...\n  }\n}\n\nemailService.addAdapter(<span class=\"hljs-keyword\">new</span> MyEmailService());\n</code></pre>\n<p>Emails should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"subject\"</span>: <span class=\"hljs-string\">\"SMTP e-mail test\"</span>,\n      <span class=\"hljs-string\">\"sent_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.567+03:00\"</span>,\n      <span class=\"hljs-string\">\"from_email\"</span>: <span class=\"hljs-string\">\"me@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"from_name\"</span>: <span class=\"hljs-string\">\"Private Person\"</span>,\n      <span class=\"hljs-string\">\"to_email\"</span>: <span class=\"hljs-string\">\"test@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"to_name\"</span>: <span class=\"hljs-string\">\"A Test User\"</span>,\n      <span class=\"hljs-string\">\"html_body\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"text_body\"</span>: <span class=\"hljs-string\">\"This is a test e-mail message.\\r\\n\"</span>,\n      <span class=\"hljs-string\">\"email_size\"</span>: <span class=\"hljs-number\">193</span>,\n      <span class=\"hljs-string\">\"is_read\"</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.576+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:09.232+03:00\"</span>,\n      <span class=\"hljs-string\">\"sent_at_timestamp\"</span>: <span class=\"hljs-number\">1377448326</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap email format.</p>\n<p>Attachments should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"id\"</span>: <span class=\"hljs-number\">1737</span>,\n      <span class=\"hljs-string\">\"message_id\"</span>: <span class=\"hljs-number\">54508</span>,\n      <span class=\"hljs-string\">\"filename\"</span>: <span class=\"hljs-string\">\"Photos.png\"</span>,\n      <span class=\"hljs-string\">\"attachment_type\"</span>: <span class=\"hljs-string\">\"attachment\"</span>,\n      <span class=\"hljs-string\">\"content_type\"</span>: <span class=\"hljs-string\">\"image/png\"</span>,\n      <span class=\"hljs-string\">\"content_id\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"transfer_encoding\"</span>: <span class=\"hljs-string\">\"base64\"</span>,\n      <span class=\"hljs-string\">\"attachment_size\"</span>: <span class=\"hljs-number\">213855</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"attachment_human_size\"</span>: <span class=\"hljs-string\">\"210 KB\"</span>,\n      <span class=\"hljs-string\">\"download_path\"</span>: <span class=\"hljs-string\">\"/api/v1/inboxes/3/messages/54508/attachments/1737/download\"</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap attachment format.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/transformers\"><span class=\"arrow-prev\">← </span><span>Transformers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/cross-browser\"><span>Cross-browser testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#internal-services\">Internal services</a><ul class=\"toc-headings\"><li><a href=\"#regex-builder\">Regex builder</a></li><li><a href=\"#variable-store\">Variable store</a></li><li><a href=\"#user-provider\">User provider</a></li></ul></li><li><a href=\"#adding-custom-code\">Adding custom code</a><ul class=\"toc-headings\"><li><a href=\"#custom-step\">Custom step</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#matchers\">Matchers</a></li><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#comparators\">Comparators</a></li><li><a href=\"#form-handlers\">Form handlers</a></li><li><a href=\"#transformers\">Transformers</a></li><li><a href=\"#email-checking-service\">Email checking service</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/how-it-works/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>How it works · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"How it works · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">How it works</h1></header><article><div><span><p>Kakunin is built with <code>no-js</code> experience in mind. Because of that you're able to test even complicated apps just\nby knowing Kakunin (Gherkin) steps and a few good practices.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"concepts\"></a><a href=\"#concepts\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Concepts</h2>\n<p>Kakunin uses <code>cucumber-js</code> internally, because of that all tests (or rather scenarios) are using <code>Gherkin</code> as a &quot;programming&quot;\nlanguage.</p>\n<p>A simple scenario could look like this:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>This is how most of Kakunin test scenarios look like.</p>\n<p>There are a few concepts to be explained.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h2>\n<p>Page object is a code representation of a page displayed in browser. Kakunin has built-in <code>BasePage</code> page object, that you should extend.</p>\n<p>Page object contains information about page url, its elements, locators, but can also have some custom methods if necessary.</p>\n<p>A very simple example of Kakunin's Page Object could look like the following:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/dashboard'</span>;\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = DashboardPage;\n</code></pre>\n<p>As you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (<code>this.url</code>).</p>\n<p>This code should be saved inside <code>pages</code> directory in a file with <code>js</code> extension.\nNote that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n</code></pre>\n<p>expects that there is a file named <code>dashboard.js</code> inside the <code>pages</code> directory.</p>\n<p>Every step that we are using is somehow connected to an object called <code>currentPage</code>. This object value is set to a\npage object that we expect to be on.</p>\n<p>This is done by two kinds of steps:</p>\n<ul>\n<li><code>Then the &quot;dashboard&quot; page is displayed</code> - this one checks if current url in browser is the same as the one inside Page Object and changes a value of the <code>currentPage</code> field\nto this page object</li>\n<li><code>When I visit the &quot;dashboard&quot; page</code> - this one goes to the url specified in Page Object and attaches the Page Object to the <code>currentPage</code> field as above</li>\n</ul>\n<p>This concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods.\nFor example, having the following code:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>The step named <code>And I click the &quot;profileButton&quot; element</code> is executed in context of <code>dashboard</code> Page Object, thus we can assume that <code>profileButton</code> should be defined inside the\n<code>pages/dashboard.js</code> file.</p>\n<p>At the same time the step <code>And the &quot;myName&quot; element is visible</code> is executed in context of <code>myProfile</code>, so <code>myName</code> should be defined in <code>pages/myProfile.js</code> file.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"elements-and-locators\"></a><a href=\"#elements-and-locators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Elements and locators</h2>\n<p>The second concept that you have to understand are elements and locators.</p>\n<p>Every element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:\n<code>And the &quot;myName&quot; element is visible</code>.</p>\n<p>Defining elements is very simple. Let's say we have such page object:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>Elements should be defined inside <code>constructor</code> method. Let's add element for <code>myName</code>:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n        \n        <span class=\"hljs-keyword\">this</span>.myName = element(by.css('.myName'));\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>As you see we added a single line <code>this.myName = element(by.css('.myName'));</code>.</p>\n<p><code>by.css('.myName')</code> - is a locator, this is a standard protractor syntax, you can read more on protractors documentation</p>\n<p>By joining <code>element</code> method with a locator, we created element to be used by our steps.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"compare-urls-examples\"></a><a href=\"#compare-urls-examples\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Compare URLs examples:</h2>\n<table>\n<thead>\n<tr><th>Page Object URL</th><th>Current Browser URL</th><th>Base URL - config file</th><th>Results</th></tr>\n</thead>\n<tbody>\n<tr><td><a href=\"http://localhost:8080/incorrect-data\">http://localhost:8080/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/incorrect-data/\">http://localhost:8080/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data\">http://google/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/tabular-data\">http://google/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data/\">http://google/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data/</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"http://incorrect.com\">http://incorrect.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data/\">http://localhost:8080/tabular-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl\">https://google.pl</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://google.com/:example/:name\">https://google.com/:example/:name</a></td><td><a href=\"https://google.com/example/janek\">https://google.com/example/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/:name\">https://google.com/:name</a></td><td><a href=\"https://google.com/janek\">https://google.com/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/account/:username/settings/display\">https://google.com/account/:username/settings/display</a></td><td><a href=\"https://google.com/account/janek/settings/display\">https://google.com/account/janek/settings/display</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType/something</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://incorrect-host/account/settings/:userType/something\">https://incorrect-host/account/settings/:userType/something</a></td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://google.com/account/settings/user\">https://google.com/account/settings/user</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>TRUE</td></tr>\n</tbody>\n</table>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/configuration\"><span class=\"arrow-prev\">← </span><span>Configuration</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/matchers\"><span>Matchers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#concepts\">Concepts</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#elements-and-locators\">Elements and locators</a></li><li><a href=\"#compare-urls-examples\">Compare URLs examples:</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/how-it-works.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>How it works · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"How it works · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">How it works</h1></header><article><div><span><p>Kakunin is built with <code>no-js</code> experience in mind. Because of that you're able to test even complicated apps just\nby knowing Kakunin (Gherkin) steps and a few good practices.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"concepts\"></a><a href=\"#concepts\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Concepts</h2>\n<p>Kakunin uses <code>cucumber-js</code> internally, because of that all tests (or rather scenarios) are using <code>Gherkin</code> as a &quot;programming&quot;\nlanguage.</p>\n<p>A simple scenario could look like this:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>This is how most of Kakunin test scenarios look like.</p>\n<p>There are a few concepts to be explained.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h2>\n<p>Page object is a code representation of a page displayed in browser. Kakunin has built-in <code>BasePage</code> page object, that you should extend.</p>\n<p>Page object contains information about page url, its elements, locators, but can also have some custom methods if necessary.</p>\n<p>A very simple example of Kakunin's Page Object could look like the following:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/dashboard'</span>;\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = DashboardPage;\n</code></pre>\n<p>As you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (<code>this.url</code>).</p>\n<p>This code should be saved inside <code>pages</code> directory in a file with <code>js</code> extension.\nNote that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n</code></pre>\n<p>expects that there is a file named <code>dashboard.js</code> inside the <code>pages</code> directory.</p>\n<p>Every step that we are using is somehow connected to an object called <code>currentPage</code>. This object value is set to a\npage object that we expect to be on.</p>\n<p>This is done by two kinds of steps:</p>\n<ul>\n<li><code>Then the &quot;dashboard&quot; page is displayed</code> - this one checks if current url in browser is the same as the one inside Page Object and changes a value of the <code>currentPage</code> field\nto this page object</li>\n<li><code>When I visit the &quot;dashboard&quot; page</code> - this one goes to the url specified in Page Object and attaches the Page Object to the <code>currentPage</code> field as above</li>\n</ul>\n<p>This concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods.\nFor example, having the following code:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>The step named <code>And I click the &quot;profileButton&quot; element</code> is executed in context of <code>dashboard</code> Page Object, thus we can assume that <code>profileButton</code> should be defined inside the\n<code>pages/dashboard.js</code> file.</p>\n<p>At the same time the step <code>And the &quot;myName&quot; element is visible</code> is executed in context of <code>myProfile</code>, so <code>myName</code> should be defined in <code>pages/myProfile.js</code> file.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"elements-and-locators\"></a><a href=\"#elements-and-locators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Elements and locators</h2>\n<p>The second concept that you have to understand are elements and locators.</p>\n<p>Every element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:\n<code>And the &quot;myName&quot; element is visible</code>.</p>\n<p>Defining elements is very simple. Let's say we have such page object:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>Elements should be defined inside <code>constructor</code> method. Let's add element for <code>myName</code>:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n        \n        <span class=\"hljs-keyword\">this</span>.myName = element(by.css('.myName'));\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>As you see we added a single line <code>this.myName = element(by.css('.myName'));</code>.</p>\n<p><code>by.css('.myName')</code> - is a locator, this is a standard protractor syntax, you can read more on protractors documentation</p>\n<p>By joining <code>element</code> method with a locator, we created element to be used by our steps.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"compare-urls-examples\"></a><a href=\"#compare-urls-examples\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Compare URLs examples:</h2>\n<table>\n<thead>\n<tr><th>Page Object URL</th><th>Current Browser URL</th><th>Base URL - config file</th><th>Results</th></tr>\n</thead>\n<tbody>\n<tr><td><a href=\"http://localhost:8080/incorrect-data\">http://localhost:8080/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/incorrect-data/\">http://localhost:8080/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data\">http://google/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/tabular-data\">http://google/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data/\">http://google/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data/</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"http://incorrect.com\">http://incorrect.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data/\">http://localhost:8080/tabular-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl\">https://google.pl</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://google.com/:example/:name\">https://google.com/:example/:name</a></td><td><a href=\"https://google.com/example/janek\">https://google.com/example/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/:name\">https://google.com/:name</a></td><td><a href=\"https://google.com/janek\">https://google.com/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/account/:username/settings/display\">https://google.com/account/:username/settings/display</a></td><td><a href=\"https://google.com/account/janek/settings/display\">https://google.com/account/janek/settings/display</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType/something</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://incorrect-host/account/settings/:userType/something\">https://incorrect-host/account/settings/:userType/something</a></td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://google.com/account/settings/user\">https://google.com/account/settings/user</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>TRUE</td></tr>\n</tbody>\n</table>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/configuration\"><span class=\"arrow-prev\">← </span><span>Configuration</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/matchers\"><span>Matchers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#concepts\">Concepts</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#elements-and-locators\">Elements and locators</a></li><li><a href=\"#compare-urls-examples\">Compare URLs examples:</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Getting started · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## About Kakunin\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Getting started · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## About Kakunin\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Getting started</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"about-kakunin\"></a><a href=\"#about-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About Kakunin</h2>\n<p>Kakunin is a Protractor extension created by The Software House sp. z o.o. and Takamol Holding. It allows you\nto write e2e test scenarios with a help of Gherkin language and JavaScript for all kind of applications - Angular, React and others.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"installation\"></a><a href=\"#installation\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Installation</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project</p>\n<pre><code class=\"hljs css language-bash\">mkdir my_project\n</code></pre>\n<p>Go to project directory</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env protractor webdriver-manager kakunin  --save\n</code></pre>\n<p>Inside <code>package.json</code> file; add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-json\">\"kakunin\": \"cross-env NODE_ENV=prod kakunin\"\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ul>\n<li>Create kakunin project</li>\n</ul>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>The above command will run Kakunin's init script.</p>\n<ul>\n<li>Answer what kind of app you're going to test (<code>default: AngularJS</code>)</li>\n<li>Enter URL where your tested app will be running (<code>default: http://localhost:3000</code>)</li>\n<li>Choose if you plan to use some emails checking service (<code>default: none</code>)</li>\n</ul>\n<p>Also, there is a possibility to answer these question by a command line.</p>\n<pre><code class=\"hljs css language-text\">npm run kakunin init -- --baseUrl https://google.com --type otherWeb --emailType none\n</code></pre>\n<p>Available parameters: <code>baseUrl</code>, <code>type</code>, <code>emailType</code>, <code>emailApiKey</code>, <code>emailInboxId</code>.\nYou will not be asked about question that you already answered by a command.</p>\n<p>After the init process, a project files should be automatically created in your directory.</p>\n<p>This is an example of a console output after the init process is completed:</p>\n<pre><code class=\"hljs css language-text\">Created file at path /Users/example-user/projects/test/kakunin.conf.js\nCreated directory at path /Users/<user>/TSHProjects/test/reports\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report/features\nCreated directory at path /Users/<user>/TSHProjects/test/reports/performance\nCreated directory at path /Users/<user>/TSHProjects/test/downloads\nCreated directory at path /Users/example-user/projects/test/data\nCreated directory at path /Users/example-user/projects/test/features\nCreated directory at path /Users/example-user/projects/test/pages\nCreated directory at path /Users/example-user/projects/test/matchers\nCreated directory at path /Users/example-user/projects/test/generators\nCreated directory at path /Users/example-user/projects/test/form_handlers\nCreated directory at path /Users/example-user/projects/test/step_definitions\nCreated directory at path /Users/example-user/projects/test/comparators\nCreated directory at path /Users/example-user/projects/test/dictionaries\nCreated directory at path /Users/example-user/projects/test/regexes\nCreated directory at path /Users/example-user/projects/test/hooks\nCreated directory at path /Users/example-user/projects/test/transformers\nCreated directory at path /Users/example-user/projects/test/emails\nCreated file at path /Users/example-user/projects/test/downloads/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/features/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/performance/.gitkeep\nCreated file at path /Users/example-user/projects/test/features/example.feature\nCreated file at path /Users/example-user/projects/test/pages/page.js\nCreated file at path /Users/example-user/projects/test/matchers/matcher.js\nCreated file at path /Users/example-user/projects/test/generators/generator.js\nCreated file at path /Users/example-user/projects/test/step_definitions/steps.js\nCreated file at path /Users/example-user/projects/test/regexes/regex.js\nCreated file at path /Users/example-user/projects/test/hooks/hook.js\n</code></pre>\n<p>And you're set! Now you can run the tests using Kakunin:</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"commands\"></a><a href=\"#commands\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Commands</h2>\n<ul>\n<li><p>Create a new project by answering few simple questions (you can pass additional parameter to enter advanced mode where you can configure all Kakunin options by yourself)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init [-- --advanced]\n</code></pre></li>\n<li><p>Run test scenarios</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags @someTag\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code> and <code>@otherTag</code> at the same time</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"@someTag and @otherTag\"</span>\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code> or <code>@otherTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"@someTag or @otherTag\"</span>\n</code></pre></li>\n<li><p>Run only scenarios not tagged by <code>@someTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"not @someTag\"</span>\n</code></pre></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting--tips\"></a><a href=\"#troubleshooting--tips\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting &amp; Tips</h2>\n<p>In order to make cucumber steps autosuggestion work properly in JetBrains tools, make sure your project is <code>ECMAScript 6</code> compatible and you have <code>cucumberjs</code> plugin installed.\nDue to non-resolved issue in Jetbrains editors (<a href=\"https://youtrack.jetbrains.com/issue/WEB-11505\">see here</a>) we'll have to do one more step:</p>\n<p>Go to <code>step_definitions</code> directory</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-built_in\">cd</span> step_definitions\n</code></pre>\n<p>Paste this code into terminal and restart your IDE:</p>\n<p>For Linux/MacOs:</p>\n<pre><code class=\"hljs css language-bash\">ln -s ../node_modules/kakunin/dist/step_definitions/elements.js kakunin-elements.js\nln -s ../node_modules/kakunin/dist/step_definitions/debug.js kakunin-debug.js\nln -s ../node_modules/kakunin/dist/step_definitions/file.js kakunin-file.js\nln -s ../node_modules/kakunin/dist/step_definitions/form.js kakunin-form.js\nln -s ../node_modules/kakunin/dist/step_definitions/email.js kakunin-email.js\nln -s ../node_modules/kakunin/dist/step_definitions/generators.js kakunin-generators.js\nln -s ../node_modules/kakunin/dist/step_definitions/navigation.js kakunin-navigation.js \nln -s ../node_modules/kakunin/dist/step_definitions/performance.js kakunin-performance.js \n</code></pre>\n<p>For Windows 8+: (you have to do this as administrator)</p>\n<pre><code class=\"hljs css language-bash\">mklink kakunin-elements.js ../node_modules/kakunin/dist/step_definitions/elements.js\nmklink kakunin-debug.js ../node_modules/kakunin/dist/step_definitions/debug.js \nmklink kakunin-file.js ../node_modules/kakunin/dist/step_definitions/file.js \nmklink kakunin-form.js ../node_modules/kakunin/dist/step_definitions/form.js \nmklink kakunin-email.js ../node_modules/kakunin/dist/step_definitions/email.js\nmklink kakunin-generators.js ../node_modules/kakunin/dist/step_definitions/generators.js \nmklink kakunin-navigation.js ../node_modules/kakunin/dist/step_definitions/navigation.js \nmklink kakunin-performance.js ../node_modules/kakunin/dist/step_definitions/performance.js \n</code></pre>\n<p>Keep in mind that <code>mklink</code> is not available in older Windows distributions.</p>\n<p>This will create symlinks inside <code>step_definitions</code> directory and make <code>cucumberjs</code> plugin recognize kakunin built-in steps.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/quickstart\"><span class=\"arrow-prev\">← </span><span>Quick start</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/configuration\"><span>Configuration</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#about-kakunin\">About Kakunin</a></li><li><a href=\"#installation\">Installation</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#commands\">Commands</a></li><li><a href=\"#troubleshooting--tips\">Troubleshooting &amp; Tips</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/matchers/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Matchers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Matchers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Matchers</h1></header><article><div><span><p>Matchers allows you to check if a element content matches your expectation.</p>\n<p>For example you can check if a value has a specified pattern or if a button is clickable.</p>\n<p>Using matcher is very straightforward, for example: <code>f:isClickable</code>.</p>\n<p>Matchers can be used in most of the steps related to checking content (with exception of checking form values).</p>\n<p>Kakunin comes with a set of built in matchers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"visibility-matcher\"></a><a href=\"#visibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Visibility matcher</h2>\n<p><code>f:isVisible</code> - checks if element is visible (must be in viewport and cannot be hidden behind any other element)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"invisibility-matcher\"></a><a href=\"#invisibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Invisibility matcher</h2>\n<p><code>f:isNotVisible</code> - checks if element is not visible</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"present-matcher\"></a><a href=\"#present-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Present matcher</h2>\n<p><code>f:isPresent</code> - checks if element is in html code (does not have to be visible)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"clickable-matcher\"></a><a href=\"#clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clickable matcher</h2>\n<p><code>f:isClickable</code> - checks if element is clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"not-clickable-matcher\"></a><a href=\"#not-clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Not clickable matcher</h2>\n<p><code>f:isNotClickable</code> - checks if element is not clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"attribute-matcher\"></a><a href=\"#attribute-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attribute matcher</h2>\n<p><code>attribute:attributeName:regexName</code> - allows to check if element has attribute with a name specified by <code>attributeName</code> and it has to\nhave a format passing <code>regexName</code></p>\n<p>For example, if there is an element:</p>\n<p><code>&lt;p custom-attribute=&quot;123123&quot;&gt;some value&lt;/p&gt;</code></p>\n<p>you can check if attribute is an number by running: <code>attribute:custom-attribute:number</code></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-matcher\"></a><a href=\"#regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex matcher</h2>\n<p><code>r:regexName</code> - allows you to run a <code>regexName</code> against a text value of element</p>\n<p>Regexes have to be specified inside <code>regex</code> directory or be a kakunin built ones:</p>\n<p><code>notEmpty</code> - there must be a value\n<code>number</code> - must be a number</p>\n<p>You can add your own matchers. In order to do so please read <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"text-matcher\"></a><a href=\"#text-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Text matcher</h2>\n<p><code>t:text you are looking for</code> - allows you to check if an element contains a expected text</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"current-date-matcher\"></a><a href=\"#current-date-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Current date matcher</h2>\n<p><code>f:currentDate:{format}</code> - allows you to generate current date, <code>{format}</code> is optional, by default <code>DD-MM-YYYY</code></p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/how-it-works\"><span class=\"arrow-prev\">← </span><span>How it works</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/transformers\"><span>Transformers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#visibility-matcher\">Visibility matcher</a></li><li><a href=\"#invisibility-matcher\">Invisibility matcher</a></li><li><a href=\"#present-matcher\">Present matcher</a></li><li><a href=\"#clickable-matcher\">Clickable matcher</a></li><li><a href=\"#not-clickable-matcher\">Not clickable matcher</a></li><li><a href=\"#attribute-matcher\">Attribute matcher</a></li><li><a href=\"#regex-matcher\">Regex matcher</a></li><li><a href=\"#text-matcher\">Text matcher</a></li><li><a href=\"#current-date-matcher\">Current date matcher</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/matchers.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Matchers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Matchers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Matchers</h1></header><article><div><span><p>Matchers allows you to check if a element content matches your expectation.</p>\n<p>For example you can check if a value has a specified pattern or if a button is clickable.</p>\n<p>Using matcher is very straightforward, for example: <code>f:isClickable</code>.</p>\n<p>Matchers can be used in most of the steps related to checking content (with exception of checking form values).</p>\n<p>Kakunin comes with a set of built in matchers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"visibility-matcher\"></a><a href=\"#visibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Visibility matcher</h2>\n<p><code>f:isVisible</code> - checks if element is visible (must be in viewport and cannot be hidden behind any other element)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"invisibility-matcher\"></a><a href=\"#invisibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Invisibility matcher</h2>\n<p><code>f:isNotVisible</code> - checks if element is not visible</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"present-matcher\"></a><a href=\"#present-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Present matcher</h2>\n<p><code>f:isPresent</code> - checks if element is in html code (does not have to be visible)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"clickable-matcher\"></a><a href=\"#clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clickable matcher</h2>\n<p><code>f:isClickable</code> - checks if element is clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"not-clickable-matcher\"></a><a href=\"#not-clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Not clickable matcher</h2>\n<p><code>f:isNotClickable</code> - checks if element is not clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"attribute-matcher\"></a><a href=\"#attribute-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attribute matcher</h2>\n<p><code>attribute:attributeName:regexName</code> - allows to check if element has attribute with a name specified by <code>attributeName</code> and it has to\nhave a format passing <code>regexName</code></p>\n<p>For example, if there is an element:</p>\n<p><code>&lt;p custom-attribute=&quot;123123&quot;&gt;some value&lt;/p&gt;</code></p>\n<p>you can check if attribute is an number by running: <code>attribute:custom-attribute:number</code></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-matcher\"></a><a href=\"#regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex matcher</h2>\n<p><code>r:regexName</code> - allows you to run a <code>regexName</code> against a text value of element</p>\n<p>Regexes have to be specified inside <code>regex</code> directory or be a kakunin built ones:</p>\n<p><code>notEmpty</code> - there must be a value\n<code>number</code> - must be a number</p>\n<p>You can add your own matchers. In order to do so please read <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"text-matcher\"></a><a href=\"#text-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Text matcher</h2>\n<p><code>t:text you are looking for</code> - allows you to check if an element contains a expected text</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"current-date-matcher\"></a><a href=\"#current-date-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Current date matcher</h2>\n<p><code>f:currentDate:{format}</code> - allows you to generate current date, <code>{format}</code> is optional, by default <code>DD-MM-YYYY</code></p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/how-it-works\"><span class=\"arrow-prev\">← </span><span>How it works</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/transformers\"><span>Transformers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#visibility-matcher\">Visibility matcher</a></li><li><a href=\"#invisibility-matcher\">Invisibility matcher</a></li><li><a href=\"#present-matcher\">Present matcher</a></li><li><a href=\"#clickable-matcher\">Clickable matcher</a></li><li><a href=\"#not-clickable-matcher\">Not clickable matcher</a></li><li><a href=\"#attribute-matcher\">Attribute matcher</a></li><li><a href=\"#regex-matcher\">Regex matcher</a></li><li><a href=\"#text-matcher\">Text matcher</a></li><li><a href=\"#current-date-matcher\">Current date matcher</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/browserstack/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Browserstack integration · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## Browserstack project configuration\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Browserstack integration · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## Browserstack project configuration\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Browserstack integration</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"browserstack-project-configuration\"></a><a href=\"#browserstack-project-configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Browserstack project configuration</h2>\n<ol>\n<li>Create a new account in Browserstack: <a href=\"https://www.browserstack.com/\">https://www.browserstack.com/</a></li>\n<li>Login and visit the website <a href=\"https://www.browserstack.com/accounts/settings\">https://www.browserstack.com/accounts/settings</a></li>\n<li>Scroll down to the <code>Automation</code> section and copy:</li>\n</ol>\n<ul>\n<li><code>Username</code></li>\n<li><code>Access Key</code></li>\n</ul>\n<ol start=\"4\">\n<li>Add a new <code>browserstack</code> section to the <code>kakunin.conf.js</code> file in the repository.\nThis is an example of a configuration for IE8 on Windows 7.</li>\n</ol>\n<pre><code class=\"hljs css language-javascript\">  browserstack: {\n    <span class=\"hljs-attr\">seleniumAddress</span>: <span class=\"hljs-string\">'http://hub-cloud.browserstack.com/wd/hub'</span>,\n    <span class=\"hljs-attr\">defaultPort</span>: <span class=\"hljs-number\">45691</span>,\n    <span class=\"hljs-attr\">capabilities</span>: {\n      <span class=\"hljs-string\">'browserstack.user'</span>: <span class=\"hljs-string\">'example-user'</span>,\n      <span class=\"hljs-string\">'browserstack.key'</span>: <span class=\"hljs-string\">'example-key'</span>,\n      <span class=\"hljs-string\">'browserstack.local'</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-attr\">nativeEvents</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">'browserstack.ie.driver'</span>: <span class=\"hljs-string\">'3.14.0'</span>,\n      <span class=\"hljs-string\">'browserstack.selenium_version'</span>: <span class=\"hljs-string\">'3.14.0'</span>,\n      <span class=\"hljs-attr\">browserName</span>: <span class=\"hljs-string\">'IE'</span>,\n      <span class=\"hljs-attr\">browser_version</span>: <span class=\"hljs-string\">'8.0'</span>,\n    }\n  },\n</code></pre>\n<ol start=\"5\">\n<li><p>Set <code>'browserstack.user'</code> to the <code>Username</code> value that you copied from the <code>Automation</code> section</p></li>\n<li><p>Set <code>'browserstack.key'</code> to the <code>Access Key</code> value that you copied from the <code>Automation</code> section</p></li>\n<li><p>Visit the link <a href=\"https://www.browserstack.com/automate/capabilities\">https://www.browserstack.com/automate/capabilities</a> if you want to find more capabilities for your project!.</p></li>\n</ol>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests-in-browserstack\"></a><a href=\"#run-tests-in-browserstack\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests in Browserstack</h2>\n<p>Runs the application with the capabilities set in <code>kakunin.conf.js</code> file through the command line:</p>\n<ul>\n<li><code>npm run kakunin -- --browserstack</code></li>\n</ul>\n<p><span style=\"color:red\">Keep in mind that all capabilities that you set via CLI will be ignored!</span></p>\n<p>For example, <code>npm run kakunin -- --safari --browserstack</code> will ignore the <code>safari</code> part.\nOnly <code>--browserstack</code> matters in case of running tests in Browserstack.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"example-kakuninconfjs-configuration-file\"></a><a href=\"#example-kakuninconfjs-configuration-file\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example kakunin.conf.js configuration file</h2>\n<p>This is an example configuration for Internet Explorer 8 on Windows 7.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-built_in\">module</span>.exports = {\n  <span class=\"hljs-attr\">browserWidth</span>: <span class=\"hljs-number\">1600</span>,\n  <span class=\"hljs-attr\">browserHeight</span>: <span class=\"hljs-number\">900</span>,\n  <span class=\"hljs-attr\">timeout</span>: <span class=\"hljs-number\">60</span>,\n  <span class=\"hljs-attr\">elementsVisibilityTimeout</span>: <span class=\"hljs-number\">5</span>,\n  <span class=\"hljs-attr\">waitForPageTimeout</span>: <span class=\"hljs-number\">5</span>,\n  <span class=\"hljs-attr\">downloadTimeout</span>: <span class=\"hljs-number\">30</span>,\n  <span class=\"hljs-attr\">reports</span>: <span class=\"hljs-string\">'/reports'</span>,\n  <span class=\"hljs-attr\">downloads</span>: <span class=\"hljs-string\">'/downloads'</span>,\n  <span class=\"hljs-attr\">data</span>: <span class=\"hljs-string\">'/data'</span>,\n  <span class=\"hljs-attr\">features</span>: [<span class=\"hljs-string\">'/features'</span>],\n  <span class=\"hljs-attr\">pages</span>: [<span class=\"hljs-string\">'/pages'</span>],\n  <span class=\"hljs-attr\">matchers</span>: [<span class=\"hljs-string\">'/matchers'</span>],\n  <span class=\"hljs-attr\">generators</span>: [<span class=\"hljs-string\">'/generators'</span>],\n  <span class=\"hljs-attr\">form_handlers</span>: [<span class=\"hljs-string\">'/form_handlers'</span>],\n  <span class=\"hljs-attr\">step_definitions</span>: [<span class=\"hljs-string\">'/step_definitions'</span>],\n  <span class=\"hljs-attr\">comparators</span>: [<span class=\"hljs-string\">'/comparators'</span>],\n  <span class=\"hljs-attr\">dictionaries</span>: [<span class=\"hljs-string\">'/dictionaries'</span>],\n  <span class=\"hljs-attr\">transformers</span>: [<span class=\"hljs-string\">'/transformers'</span>],\n  <span class=\"hljs-attr\">regexes</span>: [<span class=\"hljs-string\">'/regexes'</span>],\n  <span class=\"hljs-attr\">hooks</span>: [<span class=\"hljs-string\">'/hooks'</span>],\n  <span class=\"hljs-attr\">clearEmailInboxBeforeTests</span>: <span class=\"hljs-literal\">false</span>,\n  <span class=\"hljs-attr\">clearCookiesAfterScenario</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-attr\">clearLocalStorageAfterScenario</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-attr\">email</span>: <span class=\"hljs-literal\">null</span>,\n  <span class=\"hljs-attr\">headless</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-attr\">noGpu</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-attr\">type</span>: <span class=\"hljs-string\">'otherWeb'</span>,\n  <span class=\"hljs-attr\">baseUrl</span>: <span class=\"hljs-string\">'http://localhost:8080'</span>,\n  <span class=\"hljs-attr\">apiUrl</span>: <span class=\"hljs-string\">'http://localhost:8080/'</span>,\n  <span class=\"hljs-attr\">browserstack</span>: {\n    <span class=\"hljs-attr\">seleniumAddress</span>: <span class=\"hljs-string\">'http://hub-cloud.browserstack.com/wd/hub'</span>,\n    <span class=\"hljs-attr\">defaultPort</span>: <span class=\"hljs-number\">45691</span>,\n    <span class=\"hljs-attr\">capabilities</span>: {\n      <span class=\"hljs-string\">'browserstack.user'</span>: <span class=\"hljs-string\">'example-user'</span>,\n      <span class=\"hljs-string\">'browserstack.key'</span>: <span class=\"hljs-string\">'example-key'</span>,\n      <span class=\"hljs-string\">'browserstack.local'</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-attr\">nativeEvents</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">'browserstack.ie.driver'</span>: <span class=\"hljs-string\">'3.14.0'</span>,\n      <span class=\"hljs-string\">'browserstack.selenium_version'</span>: <span class=\"hljs-string\">'3.14.0'</span>,\n      <span class=\"hljs-attr\">browserName</span>: <span class=\"hljs-string\">'IE'</span>,\n      <span class=\"hljs-attr\">browser_version</span>: <span class=\"hljs-string\">'8.0'</span>,\n    }\n  },\n};\n</code></pre>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/cross-browser\"><span class=\"arrow-prev\">← </span><span>Cross-browser testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/headless\"><span>Headless</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#browserstack-project-configuration\">Browserstack project configuration</a></li><li><a href=\"#run-tests-in-browserstack\">Run tests in Browserstack</a></li><li><a href=\"#example-kakuninconfjs-configuration-file\">Example kakunin.conf.js configuration file</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/browserstack.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Browserstack integration · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## Browserstack project configuration\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Browserstack integration · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## Browserstack project configuration\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Browserstack integration</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"browserstack-project-configuration\"></a><a href=\"#browserstack-project-configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Browserstack project configuration</h2>\n<ol>\n<li>Create a new account in Browserstack: <a href=\"https://www.browserstack.com/\">https://www.browserstack.com/</a></li>\n<li>Login and visit the website <a href=\"https://www.browserstack.com/accounts/settings\">https://www.browserstack.com/accounts/settings</a></li>\n<li>Scroll down to the <code>Automation</code> section and copy:</li>\n</ol>\n<ul>\n<li><code>Username</code></li>\n<li><code>Access Key</code></li>\n</ul>\n<ol start=\"4\">\n<li>Add a new <code>browserstack</code> section to the <code>kakunin.conf.js</code> file in the repository.\nThis is an example of a configuration for IE8 on Windows 7.</li>\n</ol>\n<pre><code class=\"hljs css language-javascript\">  browserstack: {\n    <span class=\"hljs-attr\">seleniumAddress</span>: <span class=\"hljs-string\">'http://hub-cloud.browserstack.com/wd/hub'</span>,\n    <span class=\"hljs-attr\">defaultPort</span>: <span class=\"hljs-number\">45691</span>,\n    <span class=\"hljs-attr\">capabilities</span>: {\n      <span class=\"hljs-string\">'browserstack.user'</span>: <span class=\"hljs-string\">'example-user'</span>,\n      <span class=\"hljs-string\">'browserstack.key'</span>: <span class=\"hljs-string\">'example-key'</span>,\n      <span class=\"hljs-string\">'browserstack.local'</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-attr\">nativeEvents</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">'browserstack.ie.driver'</span>: <span class=\"hljs-string\">'3.14.0'</span>,\n      <span class=\"hljs-string\">'browserstack.selenium_version'</span>: <span class=\"hljs-string\">'3.14.0'</span>,\n      <span class=\"hljs-attr\">browserName</span>: <span class=\"hljs-string\">'IE'</span>,\n      <span class=\"hljs-attr\">browser_version</span>: <span class=\"hljs-string\">'8.0'</span>,\n    }\n  },\n</code></pre>\n<ol start=\"5\">\n<li><p>Set <code>'browserstack.user'</code> to the <code>Username</code> value that you copied from the <code>Automation</code> section</p></li>\n<li><p>Set <code>'browserstack.key'</code> to the <code>Access Key</code> value that you copied from the <code>Automation</code> section</p></li>\n<li><p>Visit the link <a href=\"https://www.browserstack.com/automate/capabilities\">https://www.browserstack.com/automate/capabilities</a> if you want to find more capabilities for your project!.</p></li>\n</ol>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests-in-browserstack\"></a><a href=\"#run-tests-in-browserstack\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests in Browserstack</h2>\n<p>Runs the application with the capabilities set in <code>kakunin.conf.js</code> file through the command line:</p>\n<ul>\n<li><code>npm run kakunin -- --browserstack</code></li>\n</ul>\n<p><span style=\"color:red\">Keep in mind that all capabilities that you set via CLI will be ignored!</span></p>\n<p>For example, <code>npm run kakunin -- --safari --browserstack</code> will ignore the <code>safari</code> part.\nOnly <code>--browserstack</code> matters in case of running tests in Browserstack.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"example-kakuninconfjs-configuration-file\"></a><a href=\"#example-kakuninconfjs-configuration-file\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example kakunin.conf.js configuration file</h2>\n<p>This is an example configuration for Internet Explorer 8 on Windows 7.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-built_in\">module</span>.exports = {\n  <span class=\"hljs-attr\">browserWidth</span>: <span class=\"hljs-number\">1600</span>,\n  <span class=\"hljs-attr\">browserHeight</span>: <span class=\"hljs-number\">900</span>,\n  <span class=\"hljs-attr\">timeout</span>: <span class=\"hljs-number\">60</span>,\n  <span class=\"hljs-attr\">elementsVisibilityTimeout</span>: <span class=\"hljs-number\">5</span>,\n  <span class=\"hljs-attr\">waitForPageTimeout</span>: <span class=\"hljs-number\">5</span>,\n  <span class=\"hljs-attr\">downloadTimeout</span>: <span class=\"hljs-number\">30</span>,\n  <span class=\"hljs-attr\">reports</span>: <span class=\"hljs-string\">'/reports'</span>,\n  <span class=\"hljs-attr\">downloads</span>: <span class=\"hljs-string\">'/downloads'</span>,\n  <span class=\"hljs-attr\">data</span>: <span class=\"hljs-string\">'/data'</span>,\n  <span class=\"hljs-attr\">features</span>: [<span class=\"hljs-string\">'/features'</span>],\n  <span class=\"hljs-attr\">pages</span>: [<span class=\"hljs-string\">'/pages'</span>],\n  <span class=\"hljs-attr\">matchers</span>: [<span class=\"hljs-string\">'/matchers'</span>],\n  <span class=\"hljs-attr\">generators</span>: [<span class=\"hljs-string\">'/generators'</span>],\n  <span class=\"hljs-attr\">form_handlers</span>: [<span class=\"hljs-string\">'/form_handlers'</span>],\n  <span class=\"hljs-attr\">step_definitions</span>: [<span class=\"hljs-string\">'/step_definitions'</span>],\n  <span class=\"hljs-attr\">comparators</span>: [<span class=\"hljs-string\">'/comparators'</span>],\n  <span class=\"hljs-attr\">dictionaries</span>: [<span class=\"hljs-string\">'/dictionaries'</span>],\n  <span class=\"hljs-attr\">transformers</span>: [<span class=\"hljs-string\">'/transformers'</span>],\n  <span class=\"hljs-attr\">regexes</span>: [<span class=\"hljs-string\">'/regexes'</span>],\n  <span class=\"hljs-attr\">hooks</span>: [<span class=\"hljs-string\">'/hooks'</span>],\n  <span class=\"hljs-attr\">clearEmailInboxBeforeTests</span>: <span class=\"hljs-literal\">false</span>,\n  <span class=\"hljs-attr\">clearCookiesAfterScenario</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-attr\">clearLocalStorageAfterScenario</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-attr\">email</span>: <span class=\"hljs-literal\">null</span>,\n  <span class=\"hljs-attr\">headless</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-attr\">noGpu</span>: <span class=\"hljs-literal\">true</span>,\n  <span class=\"hljs-attr\">type</span>: <span class=\"hljs-string\">'otherWeb'</span>,\n  <span class=\"hljs-attr\">baseUrl</span>: <span class=\"hljs-string\">'http://localhost:8080'</span>,\n  <span class=\"hljs-attr\">apiUrl</span>: <span class=\"hljs-string\">'http://localhost:8080/'</span>,\n  <span class=\"hljs-attr\">browserstack</span>: {\n    <span class=\"hljs-attr\">seleniumAddress</span>: <span class=\"hljs-string\">'http://hub-cloud.browserstack.com/wd/hub'</span>,\n    <span class=\"hljs-attr\">defaultPort</span>: <span class=\"hljs-number\">45691</span>,\n    <span class=\"hljs-attr\">capabilities</span>: {\n      <span class=\"hljs-string\">'browserstack.user'</span>: <span class=\"hljs-string\">'example-user'</span>,\n      <span class=\"hljs-string\">'browserstack.key'</span>: <span class=\"hljs-string\">'example-key'</span>,\n      <span class=\"hljs-string\">'browserstack.local'</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-attr\">nativeEvents</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">'browserstack.ie.driver'</span>: <span class=\"hljs-string\">'3.14.0'</span>,\n      <span class=\"hljs-string\">'browserstack.selenium_version'</span>: <span class=\"hljs-string\">'3.14.0'</span>,\n      <span class=\"hljs-attr\">browserName</span>: <span class=\"hljs-string\">'IE'</span>,\n      <span class=\"hljs-attr\">browser_version</span>: <span class=\"hljs-string\">'8.0'</span>,\n    }\n  },\n};\n</code></pre>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/cross-browser\"><span class=\"arrow-prev\">← </span><span>Cross-browser testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/headless\"><span>Headless</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#browserstack-project-configuration\">Browserstack project configuration</a></li><li><a href=\"#run-tests-in-browserstack\">Run tests in Browserstack</a></li><li><a href=\"#example-kakuninconfjs-configuration-file\">Example kakunin.conf.js configuration file</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/configuration/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Configuration · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## Kakunin config\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Configuration · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## Kakunin config\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Configuration</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"kakunin-config\"></a><a href=\"#kakunin-config\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Kakunin config</h2>\n<pre><code class=\"hljs\">module.exports = {\n    <span class=\"hljs-string\">\"browserWidth\"</span>: <span class=\"hljs-number\">1600</span>,\n    <span class=\"hljs-string\">\"browserHeight\"</span>: <span class=\"hljs-number\">900</span>,\n    <span class=\"hljs-string\">\"timeout\"</span>: <span class=\"hljs-number\">60</span>,\n    <span class=\"hljs-string\">\"maxEmailRepeats\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"intervalEmail\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"elementsVisibilityTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"waitForPageTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"downloadTimeout\"</span>: <span class=\"hljs-number\">30</span>,\n    <span class=\"hljs-string\">\"reports\"</span>: <span class=\"hljs-string\">\"/reports\"</span>,\n    <span class=\"hljs-string\">\"downloads\"</span>: <span class=\"hljs-string\">\"/downloads\"</span>,\n    <span class=\"hljs-string\">\"data\"</span>: <span class=\"hljs-string\">\"/data\"</span>,\n    <span class=\"hljs-string\">\"features\"</span>: [\n        <span class=\"hljs-string\">\"/features\"</span>\n    ],\n    <span class=\"hljs-string\">\"pages\"</span>: [\n        <span class=\"hljs-string\">\"/pages\"</span>\n    ],\n    <span class=\"hljs-string\">\"matchers\"</span>: [\n        <span class=\"hljs-string\">\"/matchers\"</span>\n    ],\n    <span class=\"hljs-string\">\"generators\"</span>: [\n        <span class=\"hljs-string\">\"/generators\"</span>\n    ],\n    <span class=\"hljs-string\">\"form_handlers\"</span>: [\n        <span class=\"hljs-string\">\"/form_handlers\"</span>\n    ],\n    <span class=\"hljs-string\">\"step_definitions\"</span>: [\n        <span class=\"hljs-string\">\"/step_definitions\"</span>\n    ],\n    <span class=\"hljs-string\">\"comparators\"</span>: [\n        <span class=\"hljs-string\">\"/comparators\"</span>\n    ],\n    <span class=\"hljs-string\">\"dictionaries\"</span>: [\n        <span class=\"hljs-string\">\"/dictionaries\"</span>\n    ],\n    <span class=\"hljs-string\">\"transformers\"</span>: [\n        <span class=\"hljs-string\">\"/transformers\"</span>\n    ],\n    <span class=\"hljs-string\">\"regexes\"</span>: [\n        <span class=\"hljs-string\">\"/regexes\"</span>\n    ],\n    <span class=\"hljs-string\">\"hooks\"</span>: [\n        <span class=\"hljs-string\">\"/hooks\"</span>\n    ],\n    <span class=\"hljs-string\">\"clearEmailInboxBeforeTests\"</span>: false,\n    <span class=\"hljs-string\">\"clearCookiesAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"clearLocalStorageAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"email\"</span>: null,\n    <span class=\"hljs-string\">\"headless\"</span>: false,\n    <span class=\"hljs-string\">\"noGpu\"</span>: false,\n    <span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"otherWeb\"</span>,\n    <span class=\"hljs-string\">\"baseUrl\"</span>: <span class=\"hljs-string\">\"http://localhost:8080\"</span>,\n    <span class=\"hljs-string\">\"accounts\"</span>: {\n        <span class=\"hljs-string\">\"someAccount\"</span>: {\n            <span class=\"hljs-string\">\"accounts\"</span>: [\n                {\n                    <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n                    <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n                }\n            ]\n        }\n    }\n}\n\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration-options\"></a><a href=\"#configuration-options\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration options</h2>\n<p><code>browserWidth</code> - width of browser window <code>default: 1600</code></p>\n<p><code>browserheight</code> - height of browser window <code>default: 900</code></p>\n<p><code>timeout</code> - global timeout for a single step execution in seconds <code>default: 60</code></p>\n<p><code>maxEmailRepeats</code> - maximum email repeats to catch email used in the email step</p>\n<p><code>intervalEmail</code> - interval for email checking step <code>default: 5</code> in seconds</p>\n<p><code>elementsVisibilityTimeout</code> - maximum wait timeout for element visibility <code>default: 5</code> seconds</p>\n<p><code>waitForPageTimeout</code> - maximum wait timeout for page visibility <code>default: 5</code> seconds</p>\n<p><code>downloadTimeout</code> - maximum wait timeout for file to be downloaded <code>default: 30</code> seconds</p>\n<p><code>emails</code> - array of paths to store emails related custom code</p>\n<p><code>reports</code> - path to store reports</p>\n<p><code>downloads</code> - path to store downloaded files</p>\n<p><code>data</code> - path to store test related files (for example files to be downloaded)</p>\n<p><code>feature</code> - array of paths to store features</p>\n<p><code>pages</code> - array of paths to store page objects</p>\n<p><code>matchers</code> - array of paths to store custom matchers</p>\n<p><code>generators</code> - array of paths to store custom generators</p>\n<p><code>form_handlers</code> - array of paths to store custom form handlers</p>\n<p><code>step_definitions</code> - array of paths to store custom steps</p>\n<p><code>comparators</code> - array of paths to store custom comparators</p>\n<p><code>dictionaries</code> - array of paths to store custom dictionaries</p>\n<p><code>transformers</code> - array of paths to store custom transformers</p>\n<p><code>regexes</code> - array of paths to store custom regexes</p>\n<p><code>hooks</code> - array of paths to store custom hooks</p>\n<p><code>clearEmailInboxBeforeTests</code> - flag to active clearing email inbox before tests are executed <code>default: false | true for apps with email checking functionality activated</code></p>\n<p><code>clearCookiesAfterScenario</code> - flag to activate clearing cookies after every scenario <code>default: true</code></p>\n<p><code>clearLocalStorageAfterScenario</code> - flag to activate clearing local storage after every scenario <code>default: true</code></p>\n<p><code>email</code> - email configuration <code>default: null</code></p>\n<p>for mailtrap email checking system:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"mailtrap\"</span>,\n<span class=\"hljs-string\">\"config\"</span>: {\n    <span class=\"hljs-string\">\"apiKey\"</span>: <span class=\"hljs-string\">\"your-mailtrap-api-key\"</span>,\n    <span class=\"hljs-string\">\"inboxId\"</span>: <span class=\"hljs-string\">\"your-mailtrap-inbox\"</span>,\n    <span class=\"hljs-string\">\"url\"</span>: <span class=\"hljs-string\">\"https://mailtrap.io/api/v1\"</span>\n}\n</code></pre>\n<p>for custom email checking system only type is required:</p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"custom-type\"</span>\n</code></pre>\n<p><code>headless</code> - flag to activate chrome headless browser <code>default: false</code>. Keep in mind that CLI command <code>-- --headless=false/true</code> has higher priority than the config file.</p>\n<p><code>noGpu</code> - flag to activate cpu only mode <code>default: false</code></p>\n<p><code>type</code> - type of application either <code>ng1 | ng2 | otherWeb</code></p>\n<p><code>baseUrl</code> - url of tested application</p>\n<p><code>accounts</code> - object to store accounts information. This is bound to <code>userProvider</code> and allows to use advanced email checking options like recipient checking.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"someAccount\"</span>: {\n    <span class=\"hljs-string\">\"accounts\"</span>: [\n        {\n            <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n            <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n        }\n    ]\n}\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"environment-variables\"></a><a href=\"#environment-variables\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Environment variables</h2>\n<p>Kakunin uses a single <code>.env</code> file to load ENV variables. By default there is only one:</p>\n<p><code>FIXTURES_RELOAD_HOST</code> - allows you to specify host for fixtures reloading. This allows you to use <code>@reloadFixtures</code> tag on scenarios that should restore database to starting state, before the test is running</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/index\"><span class=\"arrow-prev\">← </span><span>Getting started</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/how-it-works\"><span>How it works</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#kakunin-config\">Kakunin config</a></li><li><a href=\"#configuration-options\">Configuration options</a></li><li><a href=\"#environment-variables\">Environment variables</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/configuration.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Configuration · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## Kakunin config\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Configuration · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## Kakunin config\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Configuration</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"kakunin-config\"></a><a href=\"#kakunin-config\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Kakunin config</h2>\n<pre><code class=\"hljs\">module.exports = {\n    <span class=\"hljs-string\">\"browserWidth\"</span>: <span class=\"hljs-number\">1600</span>,\n    <span class=\"hljs-string\">\"browserHeight\"</span>: <span class=\"hljs-number\">900</span>,\n    <span class=\"hljs-string\">\"timeout\"</span>: <span class=\"hljs-number\">60</span>,\n    <span class=\"hljs-string\">\"maxEmailRepeats\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"intervalEmail\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"elementsVisibilityTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"waitForPageTimeout\"</span>: <span class=\"hljs-number\">5</span>,\n    <span class=\"hljs-string\">\"downloadTimeout\"</span>: <span class=\"hljs-number\">30</span>,\n    <span class=\"hljs-string\">\"reports\"</span>: <span class=\"hljs-string\">\"/reports\"</span>,\n    <span class=\"hljs-string\">\"downloads\"</span>: <span class=\"hljs-string\">\"/downloads\"</span>,\n    <span class=\"hljs-string\">\"data\"</span>: <span class=\"hljs-string\">\"/data\"</span>,\n    <span class=\"hljs-string\">\"features\"</span>: [\n        <span class=\"hljs-string\">\"/features\"</span>\n    ],\n    <span class=\"hljs-string\">\"pages\"</span>: [\n        <span class=\"hljs-string\">\"/pages\"</span>\n    ],\n    <span class=\"hljs-string\">\"matchers\"</span>: [\n        <span class=\"hljs-string\">\"/matchers\"</span>\n    ],\n    <span class=\"hljs-string\">\"generators\"</span>: [\n        <span class=\"hljs-string\">\"/generators\"</span>\n    ],\n    <span class=\"hljs-string\">\"form_handlers\"</span>: [\n        <span class=\"hljs-string\">\"/form_handlers\"</span>\n    ],\n    <span class=\"hljs-string\">\"step_definitions\"</span>: [\n        <span class=\"hljs-string\">\"/step_definitions\"</span>\n    ],\n    <span class=\"hljs-string\">\"comparators\"</span>: [\n        <span class=\"hljs-string\">\"/comparators\"</span>\n    ],\n    <span class=\"hljs-string\">\"dictionaries\"</span>: [\n        <span class=\"hljs-string\">\"/dictionaries\"</span>\n    ],\n    <span class=\"hljs-string\">\"transformers\"</span>: [\n        <span class=\"hljs-string\">\"/transformers\"</span>\n    ],\n    <span class=\"hljs-string\">\"regexes\"</span>: [\n        <span class=\"hljs-string\">\"/regexes\"</span>\n    ],\n    <span class=\"hljs-string\">\"hooks\"</span>: [\n        <span class=\"hljs-string\">\"/hooks\"</span>\n    ],\n    <span class=\"hljs-string\">\"clearEmailInboxBeforeTests\"</span>: false,\n    <span class=\"hljs-string\">\"clearCookiesAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"clearLocalStorageAfterScenario\"</span>: true,\n    <span class=\"hljs-string\">\"email\"</span>: null,\n    <span class=\"hljs-string\">\"headless\"</span>: false,\n    <span class=\"hljs-string\">\"noGpu\"</span>: false,\n    <span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"otherWeb\"</span>,\n    <span class=\"hljs-string\">\"baseUrl\"</span>: <span class=\"hljs-string\">\"http://localhost:8080\"</span>,\n    <span class=\"hljs-string\">\"accounts\"</span>: {\n        <span class=\"hljs-string\">\"someAccount\"</span>: {\n            <span class=\"hljs-string\">\"accounts\"</span>: [\n                {\n                    <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n                    <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n                }\n            ]\n        }\n    }\n}\n\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration-options\"></a><a href=\"#configuration-options\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration options</h2>\n<p><code>browserWidth</code> - width of browser window <code>default: 1600</code></p>\n<p><code>browserheight</code> - height of browser window <code>default: 900</code></p>\n<p><code>timeout</code> - global timeout for a single step execution in seconds <code>default: 60</code></p>\n<p><code>maxEmailRepeats</code> - maximum email repeats to catch email used in the email step</p>\n<p><code>intervalEmail</code> - interval for email checking step <code>default: 5</code> in seconds</p>\n<p><code>elementsVisibilityTimeout</code> - maximum wait timeout for element visibility <code>default: 5</code> seconds</p>\n<p><code>waitForPageTimeout</code> - maximum wait timeout for page visibility <code>default: 5</code> seconds</p>\n<p><code>downloadTimeout</code> - maximum wait timeout for file to be downloaded <code>default: 30</code> seconds</p>\n<p><code>emails</code> - array of paths to store emails related custom code</p>\n<p><code>reports</code> - path to store reports</p>\n<p><code>downloads</code> - path to store downloaded files</p>\n<p><code>data</code> - path to store test related files (for example files to be downloaded)</p>\n<p><code>feature</code> - array of paths to store features</p>\n<p><code>pages</code> - array of paths to store page objects</p>\n<p><code>matchers</code> - array of paths to store custom matchers</p>\n<p><code>generators</code> - array of paths to store custom generators</p>\n<p><code>form_handlers</code> - array of paths to store custom form handlers</p>\n<p><code>step_definitions</code> - array of paths to store custom steps</p>\n<p><code>comparators</code> - array of paths to store custom comparators</p>\n<p><code>dictionaries</code> - array of paths to store custom dictionaries</p>\n<p><code>transformers</code> - array of paths to store custom transformers</p>\n<p><code>regexes</code> - array of paths to store custom regexes</p>\n<p><code>hooks</code> - array of paths to store custom hooks</p>\n<p><code>clearEmailInboxBeforeTests</code> - flag to active clearing email inbox before tests are executed <code>default: false | true for apps with email checking functionality activated</code></p>\n<p><code>clearCookiesAfterScenario</code> - flag to activate clearing cookies after every scenario <code>default: true</code></p>\n<p><code>clearLocalStorageAfterScenario</code> - flag to activate clearing local storage after every scenario <code>default: true</code></p>\n<p><code>email</code> - email configuration <code>default: null</code></p>\n<p>for mailtrap email checking system:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"mailtrap\"</span>,\n<span class=\"hljs-string\">\"config\"</span>: {\n    <span class=\"hljs-string\">\"apiKey\"</span>: <span class=\"hljs-string\">\"your-mailtrap-api-key\"</span>,\n    <span class=\"hljs-string\">\"inboxId\"</span>: <span class=\"hljs-string\">\"your-mailtrap-inbox\"</span>,\n    <span class=\"hljs-string\">\"url\"</span>: <span class=\"hljs-string\">\"https://mailtrap.io/api/v1\"</span>\n}\n</code></pre>\n<p>for custom email checking system only type is required:</p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"type\"</span>: <span class=\"hljs-string\">\"custom-type\"</span>\n</code></pre>\n<p><code>headless</code> - flag to activate chrome headless browser <code>default: false</code>. Keep in mind that CLI command <code>-- --headless=false/true</code> has higher priority than the config file.</p>\n<p><code>noGpu</code> - flag to activate cpu only mode <code>default: false</code></p>\n<p><code>type</code> - type of application either <code>ng1 | ng2 | otherWeb</code></p>\n<p><code>baseUrl</code> - url of tested application</p>\n<p><code>accounts</code> - object to store accounts information. This is bound to <code>userProvider</code> and allows to use advanced email checking options like recipient checking.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-string\">\"someAccount\"</span>: {\n    <span class=\"hljs-string\">\"accounts\"</span>: [\n        {\n            <span class=\"hljs-string\">\"email\"</span>: <span class=\"hljs-string\">\"\"</span>,\n            <span class=\"hljs-string\">\"password\"</span>: <span class=\"hljs-string\">\"\"</span>\n        }\n    ]\n}\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"environment-variables\"></a><a href=\"#environment-variables\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Environment variables</h2>\n<p>Kakunin uses a single <code>.env</code> file to load ENV variables. By default there is only one:</p>\n<p><code>FIXTURES_RELOAD_HOST</code> - allows you to specify host for fixtures reloading. This allows you to use <code>@reloadFixtures</code> tag on scenarios that should restore database to starting state, before the test is running</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/index\"><span class=\"arrow-prev\">← </span><span>Getting started</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/how-it-works\"><span>How it works</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#kakunin-config\">Kakunin config</a></li><li><a href=\"#configuration-options\">Configuration options</a></li><li><a href=\"#environment-variables\">Environment variables</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/cross-browser/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Cross-browser testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## To run tests with specified browser\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Cross-browser testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## To run tests with specified browser\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Cross-browser testing</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-with-specified-browser\"></a><a href=\"#to-run-tests-with-specified-browser\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests with specified browser</h2>\n<p>There is a possibility to run Kakunin in various browsers:</p>\n<ul>\n<li>Google Chrome (by default) <code>npm run kakunin</code> or <code>npm run kakunin -- --chrome</code></li>\n<li>Firefox <code>npm run kakunin -- --firefox</code></li>\n<li>Safari <code>npm run kakunin -- --safari</code></li>\n<li>Internet Explorer <code>npm run kakunin -- --ie</code> <span style=\"color:blue\">(supported versions IE8, IE9, IE10, IE11)</span></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-in-different-browsers-at-once\"></a><a href=\"#to-run-tests-in-different-browsers-at-once\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests in different browsers at once</h2>\n<p>There is a possibility to run more than one instance of WebDriver by giving an extra parameter to a command line:</p>\n<ul>\n<li><code>npm run kakunin --chrome --safari</code></li>\n</ul>\n<p>Currently, there is a problem with running more than one instance of Firefox!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"safari\"></a><a href=\"#safari\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Safari</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h3>\n<ol>\n<li>Open Safari's preferences</li>\n<li>Enable &quot;Show Develop menu in menu bar&quot;</li>\n<li>Open &quot;Develop&quot; tab</li>\n<li>Enable &quot;Allow Remote Automation&quot;</li>\n</ol>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"internet-explorer\"></a><a href=\"#internet-explorer\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Internet Explorer</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"configure-the-browser\"></a><a href=\"#configure-the-browser\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure the browser</h3>\n<ol>\n<li>Open Internet options and set:</li>\n</ol>\n<ul>\n<li>IE browser zoom level to 100 procent</li>\n<li>IE Security level: keep all of the tabs either checked / unchecked (Itnernet, Local internet, Trusted sites, Restricted sites)</li>\n</ul>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h3>\n<p>Safari version 12.0:</p>\n<ul>\n<li>drag &amp; drop actions in Kakunin impossible (more details <a href=\"https://github.com/angular/protractor/issues/1526\">https://github.com/angular/protractor/issues/1526</a>)</li>\n</ul>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/hooks\"><span class=\"arrow-prev\">← </span><span>Hooks</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/browserstack\"><span>Browserstack integration</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#to-run-tests-with-specified-browser\">To run tests with specified browser</a></li><li><a href=\"#to-run-tests-in-different-browsers-at-once\">To run tests in different browsers at once</a></li><li><a href=\"#safari\">Safari</a><ul class=\"toc-headings\"><li><a href=\"#run-tests\">Run tests</a></li></ul></li><li><a href=\"#internet-explorer\">Internet Explorer</a><ul class=\"toc-headings\"><li><a href=\"#configure-the-browser\">Configure the browser</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/cross-browser.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Cross-browser testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## To run tests with specified browser\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Cross-browser testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## To run tests with specified browser\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Cross-browser testing</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-with-specified-browser\"></a><a href=\"#to-run-tests-with-specified-browser\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests with specified browser</h2>\n<p>There is a possibility to run Kakunin in various browsers:</p>\n<ul>\n<li>Google Chrome (by default) <code>npm run kakunin</code> or <code>npm run kakunin -- --chrome</code></li>\n<li>Firefox <code>npm run kakunin -- --firefox</code></li>\n<li>Safari <code>npm run kakunin -- --safari</code></li>\n<li>Internet Explorer <code>npm run kakunin -- --ie</code> <span style=\"color:blue\">(supported versions IE8, IE9, IE10, IE11)</span></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"to-run-tests-in-different-browsers-at-once\"></a><a href=\"#to-run-tests-in-different-browsers-at-once\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>To run tests in different browsers at once</h2>\n<p>There is a possibility to run more than one instance of WebDriver by giving an extra parameter to a command line:</p>\n<ul>\n<li><code>npm run kakunin --chrome --safari</code></li>\n</ul>\n<p>Currently, there is a problem with running more than one instance of Firefox!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"safari\"></a><a href=\"#safari\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Safari</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h3>\n<ol>\n<li>Open Safari's preferences</li>\n<li>Enable &quot;Show Develop menu in menu bar&quot;</li>\n<li>Open &quot;Develop&quot; tab</li>\n<li>Enable &quot;Allow Remote Automation&quot;</li>\n</ol>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"internet-explorer\"></a><a href=\"#internet-explorer\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Internet Explorer</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"configure-the-browser\"></a><a href=\"#configure-the-browser\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure the browser</h3>\n<ol>\n<li>Open Internet options and set:</li>\n</ol>\n<ul>\n<li>IE browser zoom level to 100 procent</li>\n<li>IE Security level: keep all of the tabs either checked / unchecked (Itnernet, Local internet, Trusted sites, Restricted sites)</li>\n</ul>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h3>\n<p>Safari version 12.0:</p>\n<ul>\n<li>drag &amp; drop actions in Kakunin impossible (more details <a href=\"https://github.com/angular/protractor/issues/1526\">https://github.com/angular/protractor/issues/1526</a>)</li>\n</ul>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/hooks\"><span class=\"arrow-prev\">← </span><span>Hooks</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/browserstack\"><span>Browserstack integration</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#to-run-tests-with-specified-browser\">To run tests with specified browser</a></li><li><a href=\"#to-run-tests-in-different-browsers-at-once\">To run tests in different browsers at once</a></li><li><a href=\"#safari\">Safari</a><ul class=\"toc-headings\"><li><a href=\"#run-tests\">Run tests</a></li></ul></li><li><a href=\"#internet-explorer\">Internet Explorer</a><ul class=\"toc-headings\"><li><a href=\"#configure-the-browser\">Configure the browser</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/docker/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Docker · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Docker for Kakunin tests\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Docker · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Docker for Kakunin tests\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Docker</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"docker-for-kakunin-tests\"></a><a href=\"#docker-for-kakunin-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Docker for Kakunin tests</h1>\n<p>This section explains how to run kakunin tests inside docker, below examples of Dockerfile\nand docker-compose.yml files let you build your first docker image and run tests.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dockerfile\"></a><a href=\"#dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dockerfile:</h2>\n<p>This file is responsible for building the whole environment for our e2e tests.\nIt will allow you to run tests on local and CI environments,\nby configuring and copying the whole project inside the container.\nJust simply place it inside your e2e project root.</p>\n<p>Below an example of Dockerfile</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-dockerfile\"></a><a href=\"#example-of-dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of Dockerfile:</h3>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-comment\"># Downloading selenium image and setting privileges</span>\nFROM selenium/standalone-chrome:3.14.0\nUSER root\n<span class=\"hljs-comment\"># Setting test directory</span>\nWORKDIR /app\n<span class=\"hljs-comment\"># Install openjdk-8-jdk-headless</span>\nRUN apt-get update -qqy \\\n  &amp;&amp; apt-get -qqy --no-install-recommends install \\\n    xvfb \\\n    openjdk-8-jdk-headless \\\n    curl \\\n    make \\\n  &amp;&amp; rm -rf /var/lib/apt/lists/* /var/cache/apt/*\n<span class=\"hljs-comment\"># Installing node 8 globally and setting paths</span>\nRUN <span class=\"hljs-built_in\">set</span> -x \\\n    &amp;&amp; curl -sL https://deb.nodesource.com/setup_8.x | bash - \\\n    &amp;&amp; apt-get install -y \\\n        nodejs \\\n    &amp;&amp; npm install -g npm@latest\nRUN PATH=/usr/bin/node:<span class=\"hljs-variable\">$PATH</span>\n<span class=\"hljs-comment\"># Copy tests directory with ignored files from .dockerignore</span>\nCOPY --chown=seluser:seluser . .\n<span class=\"hljs-comment\"># Removing node_modules in case of existence or lack of .dockerignore and installing from package.json</span>\nRUN rm -rf ./node_modules \\\n    &amp;&amp; npm install\n<span class=\"hljs-comment\"># Setting Xvfb</span>\nRUN <span class=\"hljs-built_in\">export</span> DISPLAY=:99.0\nUSER seluser\n</code></pre>\n<p>##docker-compose.yml</p>\n<p>Compose is a tool for defining and running multi-container Docker applications, which we use\nfor running our tests.</p>\n<p>Running command: <code>docker-compose up -d</code> will start Dockerfile script, as a result, it builds the container.</p>\n<p>Running command: <code>docker-compose build</code> or <code>docker-compose up --build</code> will\nrebuild container, if there were made any changes.</p>\n<p>Running command: <code>docker-compose run --rm e2e</code> will start running tests inside the container</p>\n<p>Composition below allows you to run e2e tests inside the container and configure it locally or\nin CI environments.</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-docker-composeyml\"></a><a href=\"#example-of-docker-composeyml\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of docker-compose.yml:</h3>\n<pre><code class=\"hljs css language-bash\">e2e:\n      build: .\n      working_dir: /app\n      <span class=\"hljs-built_in\">command</span>: sh -c <span class=\"hljs-string\">\"Xvfb -ac :99 -screen 0 1280x1024x16 &amp; npm run kakunin\"</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-run-step-by-step\"></a><a href=\"#how-to-run-step-by-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to run step by step</h3>\n<ol>\n<li>Install docker (e.g Docker for Mac),</li>\n<li>Create Dockerfile and docker-compose.yml in the root of your e2e project,</li>\n<li>Run in command line <code>docker-compose up -d</code> which will start docker and build image\nif it's not build</li>\n<li>Run in command line <code>docker-compose run --rm e2e</code> to run your tests</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/performance-testing\"><span class=\"arrow-prev\">← </span><span>Performance testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/testing-rest-api\"><span>REST API examples</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dockerfile\">Dockerfile:</a><ul class=\"toc-headings\"><li><a href=\"#example-of-dockerfile\">Example of Dockerfile:</a></li><li><a href=\"#example-of-docker-composeyml\">Example of docker-compose.yml:</a></li><li><a href=\"#how-to-run-step-by-step\">How to run step by step</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/docker.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Docker · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Docker for Kakunin tests\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Docker · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Docker for Kakunin tests\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Docker</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"docker-for-kakunin-tests\"></a><a href=\"#docker-for-kakunin-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Docker for Kakunin tests</h1>\n<p>This section explains how to run kakunin tests inside docker, below examples of Dockerfile\nand docker-compose.yml files let you build your first docker image and run tests.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dockerfile\"></a><a href=\"#dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dockerfile:</h2>\n<p>This file is responsible for building the whole environment for our e2e tests.\nIt will allow you to run tests on local and CI environments,\nby configuring and copying the whole project inside the container.\nJust simply place it inside your e2e project root.</p>\n<p>Below an example of Dockerfile</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-dockerfile\"></a><a href=\"#example-of-dockerfile\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of Dockerfile:</h3>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-comment\"># Downloading selenium image and setting privileges</span>\nFROM selenium/standalone-chrome:3.14.0\nUSER root\n<span class=\"hljs-comment\"># Setting test directory</span>\nWORKDIR /app\n<span class=\"hljs-comment\"># Install openjdk-8-jdk-headless</span>\nRUN apt-get update -qqy \\\n  &amp;&amp; apt-get -qqy --no-install-recommends install \\\n    xvfb \\\n    openjdk-8-jdk-headless \\\n    curl \\\n    make \\\n  &amp;&amp; rm -rf /var/lib/apt/lists/* /var/cache/apt/*\n<span class=\"hljs-comment\"># Installing node 8 globally and setting paths</span>\nRUN <span class=\"hljs-built_in\">set</span> -x \\\n    &amp;&amp; curl -sL https://deb.nodesource.com/setup_8.x | bash - \\\n    &amp;&amp; apt-get install -y \\\n        nodejs \\\n    &amp;&amp; npm install -g npm@latest\nRUN PATH=/usr/bin/node:<span class=\"hljs-variable\">$PATH</span>\n<span class=\"hljs-comment\"># Copy tests directory with ignored files from .dockerignore</span>\nCOPY --chown=seluser:seluser . .\n<span class=\"hljs-comment\"># Removing node_modules in case of existence or lack of .dockerignore and installing from package.json</span>\nRUN rm -rf ./node_modules \\\n    &amp;&amp; npm install\n<span class=\"hljs-comment\"># Setting Xvfb</span>\nRUN <span class=\"hljs-built_in\">export</span> DISPLAY=:99.0\nUSER seluser\n</code></pre>\n<p>##docker-compose.yml</p>\n<p>Compose is a tool for defining and running multi-container Docker applications, which we use\nfor running our tests.</p>\n<p>Running command: <code>docker-compose up -d</code> will start Dockerfile script, as a result, it builds the container.</p>\n<p>Running command: <code>docker-compose build</code> or <code>docker-compose up --build</code> will\nrebuild container, if there were made any changes.</p>\n<p>Running command: <code>docker-compose run --rm e2e</code> will start running tests inside the container</p>\n<p>Composition below allows you to run e2e tests inside the container and configure it locally or\nin CI environments.</p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-docker-composeyml\"></a><a href=\"#example-of-docker-composeyml\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of docker-compose.yml:</h3>\n<pre><code class=\"hljs css language-bash\">e2e:\n      build: .\n      working_dir: /app\n      <span class=\"hljs-built_in\">command</span>: sh -c <span class=\"hljs-string\">\"Xvfb -ac :99 -screen 0 1280x1024x16 &amp; npm run kakunin\"</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-run-step-by-step\"></a><a href=\"#how-to-run-step-by-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to run step by step</h3>\n<ol>\n<li>Install docker (e.g Docker for Mac),</li>\n<li>Create Dockerfile and docker-compose.yml in the root of your e2e project,</li>\n<li>Run in command line <code>docker-compose up -d</code> which will start docker and build image\nif it's not build</li>\n<li>Run in command line <code>docker-compose run --rm e2e</code> to run your tests</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/performance-testing\"><span class=\"arrow-prev\">← </span><span>Performance testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/testing-rest-api\"><span>REST API examples</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dockerfile\">Dockerfile:</a><ul class=\"toc-headings\"><li><a href=\"#example-of-dockerfile\">Example of Dockerfile:</a></li><li><a href=\"#example-of-docker-composeyml\">Example of docker-compose.yml:</a></li><li><a href=\"#how-to-run-step-by-step\">How to run step by step</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/extending/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Extending Kakunin · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Extending Kakunin · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Extending Kakunin</h1></header><article><div><span><p>Kakunin allows you to easily add a custom code in order to extend it's functionality.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"internal-services\"></a><a href=\"#internal-services\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Internal services</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-builder\"></a><a href=\"#regex-builder\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex builder</h3>\n<p>Regex builder is a special builder for creating <code>RegExp</code> objects based on regexp name. Internally it has access to not only to all built-in\nregular expression files, but also custom ones specified by user.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { regexBuilder } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> myRegex = regexBuilder.buildRegex(<span class=\"hljs-string\">'r:number'</span>);\n\n<span class=\"hljs-comment\">//myRegex will contain RegExp object that matches regular expression under the name \"number\" in regexes file.</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h3>\n<p>Variable store allows you to store and read some values to be used during given scenario.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { variableStore } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\nvariableStore.storeVariable(<span class=\"hljs-string\">'some-name'</span>, <span class=\"hljs-string\">'some-value'</span>);\n\n<span class=\"hljs-keyword\">const</span> myValue = variableStore.getVariableValue(<span class=\"hljs-string\">'some-name'</span>); <span class=\"hljs-comment\">//contains 'some-value'</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"user-provider\"></a><a href=\"#user-provider\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User provider</h3>\n<p>Kakunin comes with functionality that allows you to easily load credentials for a given account type - <code>UserProvider</code>.</p>\n<p>In <code>kakunin.conf.js</code> you can find a section <code>accounts</code>.</p>\n<p>The structure it has is very simple:</p>\n<pre><code class=\"hljs css language-json\">\"accounts\": {\n    \"someAccount\": {\n        \"accounts\": [\n            {\n                \"email\": \"\",\n                \"password\": \"\"\n            }\n        ]\n    }\n}\n</code></pre>\n<p><code>someAccount</code> - the name of accounts group</p>\n<p><code>accounts</code> - an array of account credentials (in order to be able to check if a <code>currentUser</code> got an email, this has to have an <code>email</code> key, otherwise account can have any kind of\nproperties)</p>\n<p>Use provider is accessible inside any kind of a step by calling <code>this.userProvider</code>. It comes with a single method:</p>\n<p><code>this.userProvider.getUser(groupName)</code> - returns an account credentials for a given user group.</p>\n<p>It is a good practice to save a current user in <code>this.currentUser</code> variable for a email checking service.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"adding-custom-code\"></a><a href=\"#adding-custom-code\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding custom code</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"custom-step\"></a><a href=\"#custom-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Custom step</h3>\n<p>In order to add a custom step, you have to create inside of a directory specified as <code>step_definitions</code> in kakunin configuration file <code>default: /step_definitions</code>.</p>\n<p>We're using <code>cucumber-js 4.X</code> so in order to add custom step you have to use <code>defineSupportCode</code> method like this:</p>\n<pre><code class=\"hljs css language-javascript\">  <span class=\"hljs-keyword\">const</span> { defineSupportCode } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n  \n  defineSupportCode(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ When }</span>) =&gt;</span> {\n    When(<span class=\"hljs-regexp\">/^I use kakunin$/</span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) </span>{\n      expect(<span class=\"hljs-literal\">true</span>).to.equal(<span class=\"hljs-literal\">true</span>);\n    });\n  });\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h3>\n<p>Kakunin comes with some built-in page objects, that should be used as a base for your page objects.</p>\n<p>In order to create a custom one, create a file inside the <code>pages</code> directory and extend the <code>BasePage</code> from kakunin package.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyPageObject</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.myElement = element(by.css(<span class=\"hljs-string\">'.some-elemnt'</span>));\n  }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MyPageObject;\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"matchers\"></a><a href=\"#matchers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Matchers</h3>\n<p>Matchers are used to compare if given value is matching our expectation. For example if a value in table is a number.</p>\n<p>You can add your own matcher as below:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { matchers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyMatcher</span> </span>{\n  isSatisfiedBy(prefix, name) {\n    <span class=\"hljs-keyword\">return</span> prefix === <span class=\"hljs-string\">'m:'</span> &amp;&amp; name === <span class=\"hljs-string\">'pending'</span>;\n  }\n \n  match(protractorElement, matcherName) {\n    <span class=\"hljs-keyword\">return</span> protractorElement.getText().then(<span class=\"hljs-function\">(<span class=\"hljs-params\">value</span>) =&gt;</span> {\n      <span class=\"hljs-keyword\">if</span> (value === <span class=\"hljs-string\">'pending'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n      }\n      \n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Matcher \"MyMatcher\" could not match value on element \"<span class=\"hljs-subst\">${protractorElement.locator()}</span>\". Expected: \"pending\", given: \"<span class=\"hljs-subst\">${value}</span>\"`</span>);\n    }); \n  }\n}\n\nmatchers.addMatcher(<span class=\"hljs-keyword\">new</span> MyMatcher());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h3>\n<p>Dictionaries allows you to present complicated values in much more readable way. For example if an element must be\nin a form of IRI <code>/some-resource/123-123-123-23</code> and you wish to use <code>pending-resource</code> as it's alias.</p>\n<p>You can add your own dictionary:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { dictionaries } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n<span class=\"hljs-keyword\">const</span> { BaseDictionary } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">TestDictionary</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BaseDictionary</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">super</span>(<span class=\"hljs-string\">'name-of-dictionary'</span>, {\n      <span class=\"hljs-string\">'pending-resource'</span>: <span class=\"hljs-string\">'/some-resource/123-123-123-23'</span>,\n      <span class=\"hljs-string\">'test-value'</span>: <span class=\"hljs-string\">'some other value'</span>\n    });\n  }\n}\n\ndictionaries.addDictionary(<span class=\"hljs-keyword\">new</span> TestDictionary());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h3>\n<p>Generators allows you to create random values</p>\n<p>You can add your own generator:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { generators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyGeneerator</span></span>{\n  isSatisfiedBy(name) {\n    <span class=\"hljs-keyword\">return</span> name === <span class=\"hljs-string\">'my-generator'</span>;\n  }\n\n  generate(params) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'some-random-value'</span>);\n  }\n}\n\ngenerators.addGenerator(<span class=\"hljs-keyword\">new</span> MyGeneerator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"comparators\"></a><a href=\"#comparators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Comparators</h3>\n<p>Comparators allows you to check if a set of values has an expected order</p>\n<p>You can add your own comparators:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { comparators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyComparator</span> </span>{\n  isSatisfiedBy(values) {\n    <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">let</span> i=<span class=\"hljs-number\">0</span>; i&lt;values.length; i++) {\n      <span class=\"hljs-keyword\">if</span> (values[i] !== <span class=\"hljs-string\">'foo'</span> &amp;&amp; values[i] !== <span class=\"hljs-string\">'bar'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n  }\n  \n  compare(values, order) {\n    <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">let</span> i = <span class=\"hljs-number\">1</span>; i &lt; values.length; i++) {\n      <span class=\"hljs-keyword\">const</span> previousValue = values[i - <span class=\"hljs-number\">1</span>];\n      <span class=\"hljs-keyword\">const</span> currentValue = values[i];\n\n      <span class=\"hljs-keyword\">if</span> (previousValue === currentValue) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">'Wrong order'</span>);\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'Foo bar!'</span>);\n  }\n};\n\ncomparators.addComparator(<span class=\"hljs-keyword\">new</span> MyComparator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"form-handlers\"></a><a href=\"#form-handlers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Form handlers</h3>\n<p>Form handlers allows you to fill the form inputs and check value of filled fields</p>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { handlers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> MyHandler {\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.registerFieldType = <span class=\"hljs-literal\">false</span>;\n    <span class=\"hljs-keyword\">this</span>.fieldType = <span class=\"hljs-string\">'default'</span>;\n  }\n\n  isSatisfiedBy(element, elementName) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(elementName === <span class=\"hljs-string\">'someElementName'</span>);\n  }\n \n  handleFill(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].clear().then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n          <span class=\"hljs-keyword\">return</span> page[elementName].sendKeys(desiredValue);\n        });\n      }\n    );\n  }\n\n  handleCheck(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].getAttribute(<span class=\"hljs-string\">'value'</span>).then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">value</span>) </span>{\n          <span class=\"hljs-keyword\">if</span> (value === desiredValue) {\n            <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve();\n          }\n\n          <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Expected <span class=\"hljs-subst\">${desiredValue}</span> got <span class=\"hljs-subst\">${value}</span> for text input element <span class=\"hljs-subst\">${elementName}</span>`</span>);\n        });\n      }\n    );\n  }\n};\n\nhandlers.addHandler(<span class=\"hljs-keyword\">new</span> MyHandler());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"transformers\"></a><a href=\"#transformers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Transformers</h3>\n<p>Transformers can be used in steps <code>When I fill the &quot;form&quot; form with:</code> and <code>And the &quot;joinOurStoreForm&quot; form is filled with:</code>.</p>\n<p>Existing transformers:</p>\n<ul>\n<li>generators (prefix: <code>g:</code>)</li>\n<li>dictionaries (prefix: <code>d:</code>)</li>\n<li>variableStore (prefix: <code>v:</code>)\nTransformers can be used in mentioned steps by using specific 'prefix', parameters are sent after <code>:</code> sign.\nExample:\n<code>g:generatorName:param:param</code></li>\n</ul>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { transformers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyTransformer</span> </span>{\n\n  isSatisfiedBy(prefix) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-string\">'yourPrefix:'</span> === prefix;\n  }\n\n  transform(value) {\n    <span class=\"hljs-comment\">//code</span>\n  }\n}\ntransformers.addTransformer(<span class=\"hljs-keyword\">new</span> MyTransformer());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"email-checking-service\"></a><a href=\"#email-checking-service\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Email checking service</h3>\n<p>You can easily check emails with Kakunin. By default we give you MailTrap client implementation, but you can easily add your own client.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { emailService } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyEmailService</span> </span>{\n  <span class=\"hljs-comment\">//you have access to full kakunin config</span>\n  isSatisfiedBy(config) {\n    <span class=\"hljs-keyword\">return</span> config.email.type === <span class=\"hljs-string\">'my-custom-email-service'</span>;\n  }\n  \n  <span class=\"hljs-comment\">//method used to clear emails before tests</span>\n  clearInbox() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to get emails - this method should return emails in format described below</span>\n  getEmails() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to retrive atachments for given email - should return attachments in format described below</span>\n  getAttachments(email) {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to mark given email as read</span>\n  markAsRead(email) {\n    ...\n  }\n}\n\nemailService.addAdapter(<span class=\"hljs-keyword\">new</span> MyEmailService());\n</code></pre>\n<p>Emails should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"subject\"</span>: <span class=\"hljs-string\">\"SMTP e-mail test\"</span>,\n      <span class=\"hljs-string\">\"sent_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.567+03:00\"</span>,\n      <span class=\"hljs-string\">\"from_email\"</span>: <span class=\"hljs-string\">\"me@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"from_name\"</span>: <span class=\"hljs-string\">\"Private Person\"</span>,\n      <span class=\"hljs-string\">\"to_email\"</span>: <span class=\"hljs-string\">\"test@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"to_name\"</span>: <span class=\"hljs-string\">\"A Test User\"</span>,\n      <span class=\"hljs-string\">\"html_body\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"text_body\"</span>: <span class=\"hljs-string\">\"This is a test e-mail message.\\r\\n\"</span>,\n      <span class=\"hljs-string\">\"email_size\"</span>: <span class=\"hljs-number\">193</span>,\n      <span class=\"hljs-string\">\"is_read\"</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.576+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:09.232+03:00\"</span>,\n      <span class=\"hljs-string\">\"sent_at_timestamp\"</span>: <span class=\"hljs-number\">1377448326</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap email format.</p>\n<p>Attachments should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"id\"</span>: <span class=\"hljs-number\">1737</span>,\n      <span class=\"hljs-string\">\"message_id\"</span>: <span class=\"hljs-number\">54508</span>,\n      <span class=\"hljs-string\">\"filename\"</span>: <span class=\"hljs-string\">\"Photos.png\"</span>,\n      <span class=\"hljs-string\">\"attachment_type\"</span>: <span class=\"hljs-string\">\"attachment\"</span>,\n      <span class=\"hljs-string\">\"content_type\"</span>: <span class=\"hljs-string\">\"image/png\"</span>,\n      <span class=\"hljs-string\">\"content_id\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"transfer_encoding\"</span>: <span class=\"hljs-string\">\"base64\"</span>,\n      <span class=\"hljs-string\">\"attachment_size\"</span>: <span class=\"hljs-number\">213855</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"attachment_human_size\"</span>: <span class=\"hljs-string\">\"210 KB\"</span>,\n      <span class=\"hljs-string\">\"download_path\"</span>: <span class=\"hljs-string\">\"/api/v1/inboxes/3/messages/54508/attachments/1737/download\"</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap attachment format.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/transformers\"><span class=\"arrow-prev\">← </span><span>Transformers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/hooks\"><span>Hooks</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#internal-services\">Internal services</a><ul class=\"toc-headings\"><li><a href=\"#regex-builder\">Regex builder</a></li><li><a href=\"#variable-store\">Variable store</a></li><li><a href=\"#user-provider\">User provider</a></li></ul></li><li><a href=\"#adding-custom-code\">Adding custom code</a><ul class=\"toc-headings\"><li><a href=\"#custom-step\">Custom step</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#matchers\">Matchers</a></li><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#comparators\">Comparators</a></li><li><a href=\"#form-handlers\">Form handlers</a></li><li><a href=\"#transformers\">Transformers</a></li><li><a href=\"#email-checking-service\">Email checking service</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/extending.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Extending Kakunin · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Extending Kakunin · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin allows you to easily add a custom code in order to extend it&#x27;s functionality.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Extending Kakunin</h1></header><article><div><span><p>Kakunin allows you to easily add a custom code in order to extend it's functionality.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"internal-services\"></a><a href=\"#internal-services\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Internal services</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-builder\"></a><a href=\"#regex-builder\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex builder</h3>\n<p>Regex builder is a special builder for creating <code>RegExp</code> objects based on regexp name. Internally it has access to not only to all built-in\nregular expression files, but also custom ones specified by user.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { regexBuilder } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> myRegex = regexBuilder.buildRegex(<span class=\"hljs-string\">'r:number'</span>);\n\n<span class=\"hljs-comment\">//myRegex will contain RegExp object that matches regular expression under the name \"number\" in regexes file.</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h3>\n<p>Variable store allows you to store and read some values to be used during given scenario.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { variableStore } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\nvariableStore.storeVariable(<span class=\"hljs-string\">'some-name'</span>, <span class=\"hljs-string\">'some-value'</span>);\n\n<span class=\"hljs-keyword\">const</span> myValue = variableStore.getVariableValue(<span class=\"hljs-string\">'some-name'</span>); <span class=\"hljs-comment\">//contains 'some-value'</span>\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"user-provider\"></a><a href=\"#user-provider\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User provider</h3>\n<p>Kakunin comes with functionality that allows you to easily load credentials for a given account type - <code>UserProvider</code>.</p>\n<p>In <code>kakunin.conf.js</code> you can find a section <code>accounts</code>.</p>\n<p>The structure it has is very simple:</p>\n<pre><code class=\"hljs css language-json\">\"accounts\": {\n    \"someAccount\": {\n        \"accounts\": [\n            {\n                \"email\": \"\",\n                \"password\": \"\"\n            }\n        ]\n    }\n}\n</code></pre>\n<p><code>someAccount</code> - the name of accounts group</p>\n<p><code>accounts</code> - an array of account credentials (in order to be able to check if a <code>currentUser</code> got an email, this has to have an <code>email</code> key, otherwise account can have any kind of\nproperties)</p>\n<p>Use provider is accessible inside any kind of a step by calling <code>this.userProvider</code>. It comes with a single method:</p>\n<p><code>this.userProvider.getUser(groupName)</code> - returns an account credentials for a given user group.</p>\n<p>It is a good practice to save a current user in <code>this.currentUser</code> variable for a email checking service.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"adding-custom-code\"></a><a href=\"#adding-custom-code\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding custom code</h2>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"custom-step\"></a><a href=\"#custom-step\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Custom step</h3>\n<p>In order to add a custom step, you have to create inside of a directory specified as <code>step_definitions</code> in kakunin configuration file <code>default: /step_definitions</code>.</p>\n<p>We're using <code>cucumber-js 4.X</code> so in order to add custom step you have to use <code>defineSupportCode</code> method like this:</p>\n<pre><code class=\"hljs css language-javascript\">  <span class=\"hljs-keyword\">const</span> { defineSupportCode } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n  \n  defineSupportCode(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ When }</span>) =&gt;</span> {\n    When(<span class=\"hljs-regexp\">/^I use kakunin$/</span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span>(<span class=\"hljs-params\"></span>) </span>{\n      expect(<span class=\"hljs-literal\">true</span>).to.equal(<span class=\"hljs-literal\">true</span>);\n    });\n  });\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h3>\n<p>Kakunin comes with some built-in page objects, that should be used as a base for your page objects.</p>\n<p>In order to create a custom one, create a file inside the <code>pages</code> directory and extend the <code>BasePage</code> from kakunin package.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyPageObject</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.myElement = element(by.css(<span class=\"hljs-string\">'.some-elemnt'</span>));\n  }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MyPageObject;\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"matchers\"></a><a href=\"#matchers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Matchers</h3>\n<p>Matchers are used to compare if given value is matching our expectation. For example if a value in table is a number.</p>\n<p>You can add your own matcher as below:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { matchers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyMatcher</span> </span>{\n  isSatisfiedBy(prefix, name) {\n    <span class=\"hljs-keyword\">return</span> prefix === <span class=\"hljs-string\">'m:'</span> &amp;&amp; name === <span class=\"hljs-string\">'pending'</span>;\n  }\n \n  match(protractorElement, matcherName) {\n    <span class=\"hljs-keyword\">return</span> protractorElement.getText().then(<span class=\"hljs-function\">(<span class=\"hljs-params\">value</span>) =&gt;</span> {\n      <span class=\"hljs-keyword\">if</span> (value === <span class=\"hljs-string\">'pending'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n      }\n      \n      <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Matcher \"MyMatcher\" could not match value on element \"<span class=\"hljs-subst\">${protractorElement.locator()}</span>\". Expected: \"pending\", given: \"<span class=\"hljs-subst\">${value}</span>\"`</span>);\n    }); \n  }\n}\n\nmatchers.addMatcher(<span class=\"hljs-keyword\">new</span> MyMatcher());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h3>\n<p>Dictionaries allows you to present complicated values in much more readable way. For example if an element must be\nin a form of IRI <code>/some-resource/123-123-123-23</code> and you wish to use <code>pending-resource</code> as it's alias.</p>\n<p>You can add your own dictionary:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { dictionaries } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n<span class=\"hljs-keyword\">const</span> { BaseDictionary } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">TestDictionary</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BaseDictionary</span> </span>{\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">super</span>(<span class=\"hljs-string\">'name-of-dictionary'</span>, {\n      <span class=\"hljs-string\">'pending-resource'</span>: <span class=\"hljs-string\">'/some-resource/123-123-123-23'</span>,\n      <span class=\"hljs-string\">'test-value'</span>: <span class=\"hljs-string\">'some other value'</span>\n    });\n  }\n}\n\ndictionaries.addDictionary(<span class=\"hljs-keyword\">new</span> TestDictionary());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h3>\n<p>Generators allows you to create random values</p>\n<p>You can add your own generator:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { generators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyGeneerator</span></span>{\n  isSatisfiedBy(name) {\n    <span class=\"hljs-keyword\">return</span> name === <span class=\"hljs-string\">'my-generator'</span>;\n  }\n\n  generate(params) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'some-random-value'</span>);\n  }\n}\n\ngenerators.addGenerator(<span class=\"hljs-keyword\">new</span> MyGeneerator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"comparators\"></a><a href=\"#comparators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Comparators</h3>\n<p>Comparators allows you to check if a set of values has an expected order</p>\n<p>You can add your own comparators:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { comparators } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyComparator</span> </span>{\n  isSatisfiedBy(values) {\n    <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">let</span> i=<span class=\"hljs-number\">0</span>; i&lt;values.length; i++) {\n      <span class=\"hljs-keyword\">if</span> (values[i] !== <span class=\"hljs-string\">'foo'</span> &amp;&amp; values[i] !== <span class=\"hljs-string\">'bar'</span>) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">false</span>;\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">true</span>;\n  }\n  \n  compare(values, order) {\n    <span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">let</span> i = <span class=\"hljs-number\">1</span>; i &lt; values.length; i++) {\n      <span class=\"hljs-keyword\">const</span> previousValue = values[i - <span class=\"hljs-number\">1</span>];\n      <span class=\"hljs-keyword\">const</span> currentValue = values[i];\n\n      <span class=\"hljs-keyword\">if</span> (previousValue === currentValue) {\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">'Wrong order'</span>);\n      }\n    }\n\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(<span class=\"hljs-string\">'Foo bar!'</span>);\n  }\n};\n\ncomparators.addComparator(<span class=\"hljs-keyword\">new</span> MyComparator());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"form-handlers\"></a><a href=\"#form-handlers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Form handlers</h3>\n<p>Form handlers allows you to fill the form inputs and check value of filled fields</p>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { handlers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">const</span> MyHandler {\n  <span class=\"hljs-keyword\">constructor</span>() {\n    <span class=\"hljs-keyword\">this</span>.registerFieldType = <span class=\"hljs-literal\">false</span>;\n    <span class=\"hljs-keyword\">this</span>.fieldType = <span class=\"hljs-string\">'default'</span>;\n  }\n\n  isSatisfiedBy(element, elementName) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve(elementName === <span class=\"hljs-string\">'someElementName'</span>);\n  }\n \n  handleFill(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].clear().then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n          <span class=\"hljs-keyword\">return</span> page[elementName].sendKeys(desiredValue);\n        });\n      }\n    );\n  }\n\n  handleCheck(page, elementName, desiredValue) {\n    <span class=\"hljs-keyword\">return</span> page[elementName].isDisplayed()\n      .then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n        <span class=\"hljs-keyword\">return</span> page[elementName].getAttribute(<span class=\"hljs-string\">'value'</span>).then(<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\">value</span>) </span>{\n          <span class=\"hljs-keyword\">if</span> (value === desiredValue) {\n            <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.resolve();\n          }\n\n          <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">Promise</span>.reject(<span class=\"hljs-string\">`Expected <span class=\"hljs-subst\">${desiredValue}</span> got <span class=\"hljs-subst\">${value}</span> for text input element <span class=\"hljs-subst\">${elementName}</span>`</span>);\n        });\n      }\n    );\n  }\n};\n\nhandlers.addHandler(<span class=\"hljs-keyword\">new</span> MyHandler());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"transformers\"></a><a href=\"#transformers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Transformers</h3>\n<p>Transformers can be used in steps <code>When I fill the &quot;form&quot; form with:</code> and <code>And the &quot;joinOurStoreForm&quot; form is filled with:</code>.</p>\n<p>Existing transformers:</p>\n<ul>\n<li>generators (prefix: <code>g:</code>)</li>\n<li>dictionaries (prefix: <code>d:</code>)</li>\n<li>variableStore (prefix: <code>v:</code>)\nTransformers can be used in mentioned steps by using specific 'prefix', parameters are sent after <code>:</code> sign.\nExample:\n<code>g:generatorName:param:param</code></li>\n</ul>\n<p>You can add your own handlers:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { transformers } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyTransformer</span> </span>{\n\n  isSatisfiedBy(prefix) {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-string\">'yourPrefix:'</span> === prefix;\n  }\n\n  transform(value) {\n    <span class=\"hljs-comment\">//code</span>\n  }\n}\ntransformers.addTransformer(<span class=\"hljs-keyword\">new</span> MyTransformer());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"email-checking-service\"></a><a href=\"#email-checking-service\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Email checking service</h3>\n<p>You can easily check emails with Kakunin. By default we give you MailTrap client implementation, but you can easily add your own client.</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { emailService } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyEmailService</span> </span>{\n  <span class=\"hljs-comment\">//you have access to full kakunin config</span>\n  isSatisfiedBy(config) {\n    <span class=\"hljs-keyword\">return</span> config.email.type === <span class=\"hljs-string\">'my-custom-email-service'</span>;\n  }\n  \n  <span class=\"hljs-comment\">//method used to clear emails before tests</span>\n  clearInbox() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to get emails - this method should return emails in format described below</span>\n  getEmails() {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to retrive atachments for given email - should return attachments in format described below</span>\n  getAttachments(email) {\n    ...\n  }\n  \n  <span class=\"hljs-comment\">//method used to mark given email as read</span>\n  markAsRead(email) {\n    ...\n  }\n}\n\nemailService.addAdapter(<span class=\"hljs-keyword\">new</span> MyEmailService());\n</code></pre>\n<p>Emails should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"subject\"</span>: <span class=\"hljs-string\">\"SMTP e-mail test\"</span>,\n      <span class=\"hljs-string\">\"sent_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.567+03:00\"</span>,\n      <span class=\"hljs-string\">\"from_email\"</span>: <span class=\"hljs-string\">\"me@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"from_name\"</span>: <span class=\"hljs-string\">\"Private Person\"</span>,\n      <span class=\"hljs-string\">\"to_email\"</span>: <span class=\"hljs-string\">\"test@railsware.com\"</span>,\n      <span class=\"hljs-string\">\"to_name\"</span>: <span class=\"hljs-string\">\"A Test User\"</span>,\n      <span class=\"hljs-string\">\"html_body\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"text_body\"</span>: <span class=\"hljs-string\">\"This is a test e-mail message.\\r\\n\"</span>,\n      <span class=\"hljs-string\">\"email_size\"</span>: <span class=\"hljs-number\">193</span>,\n      <span class=\"hljs-string\">\"is_read\"</span>: <span class=\"hljs-literal\">true</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:07.576+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-25T19:32:09.232+03:00\"</span>,\n      <span class=\"hljs-string\">\"sent_at_timestamp\"</span>: <span class=\"hljs-number\">1377448326</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap email format.</p>\n<p>Attachments should be returned as an array of objects with given schema:</p>\n<pre><code class=\"hljs css language-javascript\">  [\n    {\n      <span class=\"hljs-string\">\"id\"</span>: <span class=\"hljs-number\">1737</span>,\n      <span class=\"hljs-string\">\"message_id\"</span>: <span class=\"hljs-number\">54508</span>,\n      <span class=\"hljs-string\">\"filename\"</span>: <span class=\"hljs-string\">\"Photos.png\"</span>,\n      <span class=\"hljs-string\">\"attachment_type\"</span>: <span class=\"hljs-string\">\"attachment\"</span>,\n      <span class=\"hljs-string\">\"content_type\"</span>: <span class=\"hljs-string\">\"image/png\"</span>,\n      <span class=\"hljs-string\">\"content_id\"</span>: <span class=\"hljs-string\">\"\"</span>,\n      <span class=\"hljs-string\">\"transfer_encoding\"</span>: <span class=\"hljs-string\">\"base64\"</span>,\n      <span class=\"hljs-string\">\"attachment_size\"</span>: <span class=\"hljs-number\">213855</span>,\n      <span class=\"hljs-string\">\"created_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"updated_at\"</span>: <span class=\"hljs-string\">\"2013-08-16T00:39:34.677+03:00\"</span>,\n      <span class=\"hljs-string\">\"attachment_human_size\"</span>: <span class=\"hljs-string\">\"210 KB\"</span>,\n      <span class=\"hljs-string\">\"download_path\"</span>: <span class=\"hljs-string\">\"/api/v1/inboxes/3/messages/54508/attachments/1737/download\"</span>\n    }\n  ]\n</code></pre>\n<p>this is MailTrap attachment format.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/transformers\"><span class=\"arrow-prev\">← </span><span>Transformers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/hooks\"><span>Hooks</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#internal-services\">Internal services</a><ul class=\"toc-headings\"><li><a href=\"#regex-builder\">Regex builder</a></li><li><a href=\"#variable-store\">Variable store</a></li><li><a href=\"#user-provider\">User provider</a></li></ul></li><li><a href=\"#adding-custom-code\">Adding custom code</a><ul class=\"toc-headings\"><li><a href=\"#custom-step\">Custom step</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#matchers\">Matchers</a></li><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#comparators\">Comparators</a></li><li><a href=\"#form-handlers\">Form handlers</a></li><li><a href=\"#transformers\">Transformers</a></li><li><a href=\"#email-checking-service\">Email checking service</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/headless/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Headless · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Headless browser control\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Headless · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Headless browser control\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Headless</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"headless-browser-control\"></a><a href=\"#headless-browser-control\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Headless browser control</h1>\n<p>Currently only Firefox and Google Chrome browser can be run headless.</p>\n<p>For the rest of the supported browsers this flag is ignored.</p>\n<p>To control headless via command line:</p>\n<ul>\n<li><code>npm run kakunin -- --headless</code> opens browser in headless mode</li>\n<li><code>npm run kakunin -- --headless=true</code> opens browser in headless mode</li>\n<li><code>npm run kakunin -- --headless=false</code> opens browser in normal mode</li>\n</ul>\n<p>Also, there is a possibility to set <code>&quot;headless: &quot;true&quot;</code> or <code>&quot;headless: &quot;false&quot;</code> in the <code>kakunin.conf.js</code> config file.</p>\n<p><span style=\"color:red\">Keep in mind that CLI has greater prority than the cofig file (overides settings on runtime).</span></p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/browserstack\"><span class=\"arrow-prev\">← </span><span>Browserstack integration</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/parallel-testing\"><span>Parallel testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/headless.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Headless · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Headless browser control\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Headless · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Headless browser control\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Headless</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"headless-browser-control\"></a><a href=\"#headless-browser-control\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Headless browser control</h1>\n<p>Currently only Firefox and Google Chrome browser can be run headless.</p>\n<p>For the rest of the supported browsers this flag is ignored.</p>\n<p>To control headless via command line:</p>\n<ul>\n<li><code>npm run kakunin -- --headless</code> opens browser in headless mode</li>\n<li><code>npm run kakunin -- --headless=true</code> opens browser in headless mode</li>\n<li><code>npm run kakunin -- --headless=false</code> opens browser in normal mode</li>\n</ul>\n<p>Also, there is a possibility to set <code>&quot;headless: &quot;true&quot;</code> or <code>&quot;headless: &quot;false&quot;</code> in the <code>kakunin.conf.js</code> config file.</p>\n<p><span style=\"color:red\">Keep in mind that CLI has greater prority than the cofig file (overides settings on runtime).</span></p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/browserstack\"><span class=\"arrow-prev\">← </span><span>Browserstack integration</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/parallel-testing\"><span>Parallel testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/hooks/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Hooks · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Hooks for Kakunin tests\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Hooks · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Hooks for Kakunin tests\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Hooks</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"hooks-for-kakunin-tests\"></a><a href=\"#hooks-for-kakunin-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hooks for Kakunin tests</h1>\n<p>This section explains how to add priority hooks for kakunin tests based on the built-in adapter.\nHooks allow you to perform actions before and after scenario.\nFor example, it lets you clear all files from the downloads folder.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-add-hook-with-priority\"></a><a href=\"#how-to-add-hook-with-priority\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to add hook with priority:</h2>\n<h5><a class=\"anchor\" aria-hidden=\"true\" id=\"initializehook\"></a><a href=\"#initializehook\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>initializeHook()</h5>\n<ul>\n<li>this method is provided to execute hook logic.</li>\n</ul>\n<h5><a class=\"anchor\" aria-hidden=\"true\" id=\"getpriority\"></a><a href=\"#getpriority\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>getPriority()</h5>\n<ul>\n<li>this method returns numeric value and then it's sorted in order.</li>\n</ul>\n<pre><code class=\"hljs css language-text\">Remember that new Hook must contain these 2 methods to fulfill interface.\n</code></pre>\n<p>After your hook is ready to use method <code>hookHandlers.addHook(Hook object)</code></p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-examplehookjs\"></a><a href=\"#example-of-examplehookjs\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of example.hook.js:</h3>\n<pre><code class=\"hljs css language-typescript\"><span class=\"hljs-keyword\">const</span> { hookHandlers, Before } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">class</span> ExampleHook {\n  initializeHook() {\n    Before(<span class=\"hljs-function\"><span class=\"hljs-params\">()</span> =&gt;</span> {\n      <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">'This hook is going to be 5th in order'</span>);\n    });\n  }\n\n  getPriority() {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">5</span>;\n  }\n}\n\nhookHandlers.addHook(<span class=\"hljs-keyword\">new</span> ExampleHook());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"build-in-hooks\"></a><a href=\"#build-in-hooks\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Build in hooks:</h3>\n<h4><a class=\"anchor\" aria-hidden=\"true\" id=\"clear-download\"></a><a href=\"#clear-download\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clear download:</h4>\n<ul>\n<li>Clears download folder before or/and after scenario. To use them add <code>@downloadClearBefore</code> or <code>@downloadClearAfter</code> tag.\nIts priority is set to 1.</li>\n</ul>\n<h4><a class=\"anchor\" aria-hidden=\"true\" id=\"reload-fixtures\"></a><a href=\"#reload-fixtures\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reload fixtures:</h4>\n<ul>\n<li>allows you to reload fixtures before the desired scenario, via URL provided in <code>.env</code> file.\nIts priority is set to 2.</li>\n</ul>\n<h4><a class=\"anchor\" aria-hidden=\"true\" id=\"take-a-screenshot-and-clear-variables\"></a><a href=\"#take-a-screenshot-and-clear-variables\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Take a screenshot and clear variables:</h4>\n<ul>\n<li>These hooks are used by kakunin mechanism to clear variable store and take screenshots after scenarios.\nTheir priority is set to 1.</li>\n</ul>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/extending\"><span class=\"arrow-prev\">← </span><span>Extending Kakunin</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/cross-browser\"><span>Cross-browser testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#how-to-add-hook-with-priority\">How to add hook with priority:</a><ul class=\"toc-headings\"><li><a href=\"#example-of-examplehookjs\">Example of example.hook.js:</a></li><li><a href=\"#build-in-hooks\">Build in hooks:</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/hooks.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Hooks · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Hooks for Kakunin tests\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Hooks · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Hooks for Kakunin tests\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Hooks</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"hooks-for-kakunin-tests\"></a><a href=\"#hooks-for-kakunin-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hooks for Kakunin tests</h1>\n<p>This section explains how to add priority hooks for kakunin tests based on the built-in adapter.\nHooks allow you to perform actions before and after scenario.\nFor example, it lets you clear all files from the downloads folder.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-add-hook-with-priority\"></a><a href=\"#how-to-add-hook-with-priority\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to add hook with priority:</h2>\n<h5><a class=\"anchor\" aria-hidden=\"true\" id=\"initializehook\"></a><a href=\"#initializehook\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>initializeHook()</h5>\n<ul>\n<li>this method is provided to execute hook logic.</li>\n</ul>\n<h5><a class=\"anchor\" aria-hidden=\"true\" id=\"getpriority\"></a><a href=\"#getpriority\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>getPriority()</h5>\n<ul>\n<li>this method returns numeric value and then it's sorted in order.</li>\n</ul>\n<pre><code class=\"hljs css language-text\">Remember that new Hook must contain these 2 methods to fulfill interface.\n</code></pre>\n<p>After your hook is ready to use method <code>hookHandlers.addHook(Hook object)</code></p>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"example-of-examplehookjs\"></a><a href=\"#example-of-examplehookjs\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example of example.hook.js:</h3>\n<pre><code class=\"hljs css language-typescript\"><span class=\"hljs-keyword\">const</span> { hookHandlers, Before } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-keyword\">class</span> ExampleHook {\n  initializeHook() {\n    Before(<span class=\"hljs-function\"><span class=\"hljs-params\">()</span> =&gt;</span> {\n      <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">'This hook is going to be 5th in order'</span>);\n    });\n  }\n\n  getPriority() {\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">5</span>;\n  }\n}\n\nhookHandlers.addHook(<span class=\"hljs-keyword\">new</span> ExampleHook());\n</code></pre>\n<h3><a class=\"anchor\" aria-hidden=\"true\" id=\"build-in-hooks\"></a><a href=\"#build-in-hooks\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Build in hooks:</h3>\n<h4><a class=\"anchor\" aria-hidden=\"true\" id=\"clear-download\"></a><a href=\"#clear-download\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clear download:</h4>\n<ul>\n<li>Clears download folder before or/and after scenario. To use them add <code>@downloadClearBefore</code> or <code>@downloadClearAfter</code> tag.\nIts priority is set to 1.</li>\n</ul>\n<h4><a class=\"anchor\" aria-hidden=\"true\" id=\"reload-fixtures\"></a><a href=\"#reload-fixtures\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reload fixtures:</h4>\n<ul>\n<li>allows you to reload fixtures before the desired scenario, via URL provided in <code>.env</code> file.\nIts priority is set to 2.</li>\n</ul>\n<h4><a class=\"anchor\" aria-hidden=\"true\" id=\"take-a-screenshot-and-clear-variables\"></a><a href=\"#take-a-screenshot-and-clear-variables\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Take a screenshot and clear variables:</h4>\n<ul>\n<li>These hooks are used by kakunin mechanism to clear variable store and take screenshots after scenarios.\nTheir priority is set to 1.</li>\n</ul>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/extending\"><span class=\"arrow-prev\">← </span><span>Extending Kakunin</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/cross-browser\"><span>Cross-browser testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#how-to-add-hook-with-priority\">How to add hook with priority:</a><ul class=\"toc-headings\"><li><a href=\"#example-of-examplehookjs\">Example of example.hook.js:</a></li><li><a href=\"#build-in-hooks\">Build in hooks:</a></li></ul></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/how-it-works/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>How it works · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"How it works · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">How it works</h1></header><article><div><span><p>Kakunin is built with <code>no-js</code> experience in mind. Because of that you're able to test even complicated apps just\nby knowing Kakunin (Gherkin) steps and a few good practices.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"concepts\"></a><a href=\"#concepts\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Concepts</h2>\n<p>Kakunin uses <code>cucumber-js</code> internally, because of that all tests (or rather scenarios) are using <code>Gherkin</code> as a &quot;programming&quot;\nlanguage.</p>\n<p>A simple scenario could look like this:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>This is how most of Kakunin test scenarios look like.</p>\n<p>There are a few concepts to be explained.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h2>\n<p>Page object is a code representation of a page displayed in browser. Kakunin has built-in <code>BasePage</code> page object, that you should extend.</p>\n<p>Page object contains information about page url, its elements, locators, but can also have some custom methods if necessary.</p>\n<p>A very simple example of Kakunin's Page Object could look like the following:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/dashboard'</span>;\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = DashboardPage;\n</code></pre>\n<p>As you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (<code>this.url</code>).</p>\n<p>This code should be saved inside <code>pages</code> directory in a file with <code>js</code> extension.\nNote that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n</code></pre>\n<p>expects that there is a file named <code>dashboard.js</code> inside the <code>pages</code> directory.</p>\n<p>Every step that we are using is somehow connected to an object called <code>currentPage</code>. This object value is set to a\npage object that we expect to be on.</p>\n<p>This is done by two kinds of steps:</p>\n<ul>\n<li><code>Then the &quot;dashboard&quot; page is displayed</code> - this one checks if current url in browser is the same as the one inside Page Object and changes a value of the <code>currentPage</code> field\nto this page object</li>\n<li><code>When I visit the &quot;dashboard&quot; page</code> - this one goes to the url specified in Page Object and attaches the Page Object to the <code>currentPage</code> field as above</li>\n</ul>\n<p>This concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods.\nFor example, having the following code:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>The step named <code>And I click the &quot;profileButton&quot; element</code> is executed in context of <code>dashboard</code> Page Object, thus we can assume that <code>profileButton</code> should be defined inside the\n<code>pages/dashboard.js</code> file.</p>\n<p>At the same time the step <code>And the &quot;myName&quot; element is visible</code> is executed in context of <code>myProfile</code>, so <code>myName</code> should be defined in <code>pages/myProfile.js</code> file.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"elements-and-locators\"></a><a href=\"#elements-and-locators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Elements and locators</h2>\n<p>The second concept that you have to understand are elements and locators.</p>\n<p>Every element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:\n<code>And the &quot;myName&quot; element is visible</code>.</p>\n<p>Defining elements is very simple. Let's say we have such page object:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>Elements should be defined inside <code>constructor</code> method. Let's add element for <code>myName</code>:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n        \n        <span class=\"hljs-keyword\">this</span>.myName = element(by.css('.myName'));\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>As you see we added a single line <code>this.myName = element(by.css('.myName'));</code>.</p>\n<p><code>by.css('.myName')</code> - is a locator, this is a standard protractor syntax, you can read more on protractors documentation</p>\n<p>By joining <code>element</code> method with a locator, we created element to be used by our steps.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"compare-urls-examples\"></a><a href=\"#compare-urls-examples\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Compare URLs examples:</h2>\n<table>\n<thead>\n<tr><th>Page Object URL</th><th>Current Browser URL</th><th>Base URL - config file</th><th>Results</th></tr>\n</thead>\n<tbody>\n<tr><td><a href=\"http://localhost:8080/incorrect-data\">http://localhost:8080/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/incorrect-data/\">http://localhost:8080/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data\">http://google/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/tabular-data\">http://google/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data/\">http://google/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data/</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"http://incorrect.com\">http://incorrect.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data/\">http://localhost:8080/tabular-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl\">https://google.pl</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://google.com/:example/:name\">https://google.com/:example/:name</a></td><td><a href=\"https://google.com/example/janek\">https://google.com/example/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/:name\">https://google.com/:name</a></td><td><a href=\"https://google.com/janek\">https://google.com/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/account/:username/settings/display\">https://google.com/account/:username/settings/display</a></td><td><a href=\"https://google.com/account/janek/settings/display\">https://google.com/account/janek/settings/display</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType/something</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://incorrect-host/account/settings/:userType/something\">https://incorrect-host/account/settings/:userType/something</a></td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://google.com/account/settings/user\">https://google.com/account/settings/user</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>TRUE</td></tr>\n</tbody>\n</table>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/configuration\"><span class=\"arrow-prev\">← </span><span>Configuration</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/matchers\"><span>Matchers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#concepts\">Concepts</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#elements-and-locators\">Elements and locators</a></li><li><a href=\"#compare-urls-examples\">Compare URLs examples:</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/how-it-works.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>How it works · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"How it works · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Kakunin is built with `no-js` experience in mind. Because of that you&#x27;re able to test even complicated apps just\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">How it works</h1></header><article><div><span><p>Kakunin is built with <code>no-js</code> experience in mind. Because of that you're able to test even complicated apps just\nby knowing Kakunin (Gherkin) steps and a few good practices.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"concepts\"></a><a href=\"#concepts\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Concepts</h2>\n<p>Kakunin uses <code>cucumber-js</code> internally, because of that all tests (or rather scenarios) are using <code>Gherkin</code> as a &quot;programming&quot;\nlanguage.</p>\n<p>A simple scenario could look like this:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>This is how most of Kakunin test scenarios look like.</p>\n<p>There are a few concepts to be explained.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"page-objects\"></a><a href=\"#page-objects\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Page objects</h2>\n<p>Page object is a code representation of a page displayed in browser. Kakunin has built-in <code>BasePage</code> page object, that you should extend.</p>\n<p>Page object contains information about page url, its elements, locators, but can also have some custom methods if necessary.</p>\n<p>A very simple example of Kakunin's Page Object could look like the following:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/dashboard'</span>;\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = DashboardPage;\n</code></pre>\n<p>As you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (<code>this.url</code>).</p>\n<p>This code should be saved inside <code>pages</code> directory in a file with <code>js</code> extension.\nNote that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n</code></pre>\n<p>expects that there is a file named <code>dashboard.js</code> inside the <code>pages</code> directory.</p>\n<p>Every step that we are using is somehow connected to an object called <code>currentPage</code>. This object value is set to a\npage object that we expect to be on.</p>\n<p>This is done by two kinds of steps:</p>\n<ul>\n<li><code>Then the &quot;dashboard&quot; page is displayed</code> - this one checks if current url in browser is the same as the one inside Page Object and changes a value of the <code>currentPage</code> field\nto this page object</li>\n<li><code>When I visit the &quot;dashboard&quot; page</code> - this one goes to the url specified in Page Object and attaches the Page Object to the <code>currentPage</code> field as above</li>\n</ul>\n<p>This concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods.\nFor example, having the following code:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n    <span class=\"hljs-keyword\">Scenario</span>: Display user profile for logged user\n        <span class=\"hljs-keyword\">Given</span> I am logged in as a <span class=\"hljs-string\">\"user\"</span>\n        <span class=\"hljs-keyword\">When</span> the <span class=\"hljs-string\">\"dashboard\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> I click the <span class=\"hljs-string\">\"profileButton\"</span> element\n        <span class=\"hljs-keyword\">Then</span> the <span class=\"hljs-string\">\"myProfile\"</span> page is displayed\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"myName\"</span> element is visible\n</code></pre>\n<p>The step named <code>And I click the &quot;profileButton&quot; element</code> is executed in context of <code>dashboard</code> Page Object, thus we can assume that <code>profileButton</code> should be defined inside the\n<code>pages/dashboard.js</code> file.</p>\n<p>At the same time the step <code>And the &quot;myName&quot; element is visible</code> is executed in context of <code>myProfile</code>, so <code>myName</code> should be defined in <code>pages/myProfile.js</code> file.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"elements-and-locators\"></a><a href=\"#elements-and-locators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Elements and locators</h2>\n<p>The second concept that you have to understand are elements and locators.</p>\n<p>Every element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:\n<code>And the &quot;myName&quot; element is visible</code>.</p>\n<p>Defining elements is very simple. Let's say we have such page object:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>Elements should be defined inside <code>constructor</code> method. Let's add element for <code>myName</code>:</p>\n<pre><code class=\"hljs\">const { <span class=\"hljs-type\">BasePage</span> } = require(<span class=\"hljs-symbol\">'kakuni</span>n');\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DashboardPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    constructor() {\n        <span class=\"hljs-keyword\">super</span>();\n        \n        <span class=\"hljs-keyword\">this</span>.url = '/dashboard';\n        \n        <span class=\"hljs-keyword\">this</span>.myName = element(by.css('.myName'));\n    }\n}\n\nmodule.exports = <span class=\"hljs-type\">DashboardPage</span>;\n</code></pre>\n<p>As you see we added a single line <code>this.myName = element(by.css('.myName'));</code>.</p>\n<p><code>by.css('.myName')</code> - is a locator, this is a standard protractor syntax, you can read more on protractors documentation</p>\n<p>By joining <code>element</code> method with a locator, we created element to be used by our steps.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"compare-urls-examples\"></a><a href=\"#compare-urls-examples\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Compare URLs examples:</h2>\n<table>\n<thead>\n<tr><th>Page Object URL</th><th>Current Browser URL</th><th>Base URL - config file</th><th>Results</th></tr>\n</thead>\n<tbody>\n<tr><td><a href=\"http://localhost:8080/incorrect-data\">http://localhost:8080/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/incorrect-data/\">http://localhost:8080/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data\">http://google/incorrect-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/tabular-data\">http://google/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://google/incorrect-data/\">http://google/incorrect-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/incorrect-data/</td><td><a href=\"http://website.com/tabular-data\">http://website.com/tabular-data</a></td><td><a href=\"http://incorrect.com\">http://incorrect.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"http://localhost:8080/tabular-data/\">http://localhost:8080/tabular-data/</a></td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/tabular-data</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/tabular-data/</td><td><a href=\"http://localhost:8080/tabular-data\">http://localhost:8080/tabular-data</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"https://google.pl/new\">https://google.pl/new</a></td><td><a href=\"https://google.pl\">https://google.pl</a></td><td>FALSE</td></tr>\n<tr><td></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td><a href=\"http://localhost:8080\">http://localhost:8080</a></td><td>TRUE</td></tr>\n<tr><td>/</td><td><a href=\"https://google.pl\">https://google.pl</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://google.com/:example/:name\">https://google.com/:example/:name</a></td><td><a href=\"https://google.com/example/janek\">https://google.com/example/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/:name\">https://google.com/:name</a></td><td><a href=\"https://google.com/janek\">https://google.com/janek</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td><a href=\"https://google.com/account/:username/settings/display\">https://google.com/account/:username/settings/display</a></td><td><a href=\"https://google.com/account/janek/settings/display\">https://google.com/account/janek/settings/display</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>TRUE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType/something</td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td><a href=\"https://incorrect-host/account/settings/:userType/something\">https://incorrect-host/account/settings/:userType/something</a></td><td><a href=\"https://incorrect-host/account/settings/admin\">https://incorrect-host/account/settings/admin</a></td><td><a href=\"https://example-url.com\">https://example-url.com</a></td><td>FALSE</td></tr>\n<tr><td>/account/settings/:userType</td><td><a href=\"https://google.com/account/settings/user\">https://google.com/account/settings/user</a></td><td><a href=\"https://google.com\">https://google.com</a></td><td>TRUE</td></tr>\n</tbody>\n</table>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/configuration\"><span class=\"arrow-prev\">← </span><span>Configuration</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/matchers\"><span>Matchers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#concepts\">Concepts</a></li><li><a href=\"#page-objects\">Page objects</a></li><li><a href=\"#elements-and-locators\">Elements and locators</a></li><li><a href=\"#compare-urls-examples\">Compare URLs examples:</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Getting started · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"## About Kakunin\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Getting started · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"## About Kakunin\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Getting started</h1></header><article><div><span><h2><a class=\"anchor\" aria-hidden=\"true\" id=\"about-kakunin\"></a><a href=\"#about-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About Kakunin</h2>\n<p>Kakunin is a Protractor extension created by The Software House sp. z o.o. and Takamol Holding. It allows you\nto write e2e test scenarios with a help of Gherkin language and JavaScript for all kind of applications - Angular, React and others.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"installation\"></a><a href=\"#installation\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Installation</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project</p>\n<pre><code class=\"hljs css language-bash\">mkdir my_project\n</code></pre>\n<p>Go to project directory</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env kakunin --save\n</code></pre>\n<p>Inside <code>package.json</code> file; add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-json\">\"kakunin\": \"cross-env NODE_ENV=prod kakunin\"\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ul>\n<li>Create kakunin project</li>\n</ul>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>The above command will run Kakunin's init script.</p>\n<ul>\n<li>Answer what kind of app you're going to test (<code>default: AngularJS</code>)</li>\n<li>Enter URL where your tested app will be running (<code>default: http://localhost:3000</code>)</li>\n<li>Choose if you plan to use some emails checking service (<code>default: none</code>)</li>\n</ul>\n<p>Also, there is a possibility to answer these question by a command line.</p>\n<pre><code class=\"hljs css language-text\">npm run kakunin init -- --baseUrl https://google.com --type otherWeb --emailType none\n</code></pre>\n<p>Available parameters: <code>baseUrl</code>, <code>type</code>, <code>emailType</code>, <code>emailApiKey</code>, <code>emailInboxId</code>.\nYou will not be asked about question that you already answered by a command.</p>\n<p>After the init process, a project files should be automatically created in your directory.</p>\n<p>This is an example of a console output after the init process is completed:</p>\n<pre><code class=\"hljs css language-text\">Created file at path /Users/example-user/projects/test/kakunin.conf.js\nCreated directory at path /Users/<user>/TSHProjects/test/reports\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report/features\nCreated directory at path /Users/<user>/TSHProjects/test/reports/performance\nCreated directory at path /Users/<user>/TSHProjects/test/downloads\nCreated directory at path /Users/example-user/projects/test/data\nCreated directory at path /Users/example-user/projects/test/features\nCreated directory at path /Users/example-user/projects/test/pages\nCreated directory at path /Users/example-user/projects/test/matchers\nCreated directory at path /Users/example-user/projects/test/generators\nCreated directory at path /Users/example-user/projects/test/form_handlers\nCreated directory at path /Users/example-user/projects/test/step_definitions\nCreated directory at path /Users/example-user/projects/test/comparators\nCreated directory at path /Users/example-user/projects/test/dictionaries\nCreated directory at path /Users/example-user/projects/test/regexes\nCreated directory at path /Users/example-user/projects/test/hooks\nCreated directory at path /Users/example-user/projects/test/transformers\nCreated directory at path /Users/example-user/projects/test/emails\nCreated file at path /Users/example-user/projects/test/downloads/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/features/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/performance/.gitkeep\nCreated file at path /Users/example-user/projects/test/features/example.feature\nCreated file at path /Users/example-user/projects/test/pages/page.js\nCreated file at path /Users/example-user/projects/test/matchers/matcher.js\nCreated file at path /Users/example-user/projects/test/generators/generator.js\nCreated file at path /Users/example-user/projects/test/step_definitions/steps.js\nCreated file at path /Users/example-user/projects/test/regexes/regex.js\nCreated file at path /Users/example-user/projects/test/hooks/hook.js\n</code></pre>\n<p>And you're set! Now you can run the tests using Kakunin:</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"commands\"></a><a href=\"#commands\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Commands</h2>\n<ul>\n<li><p>Create a new project by answering few simple questions (you can pass additional parameter to enter advanced mode where you can configure all Kakunin options by yourself)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init [-- --advanced]\n</code></pre></li>\n<li><p>Run test scenarios</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags @someTag\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code> and <code>@otherTag</code> at the same time</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"@someTag and @otherTag\"</span>\n</code></pre></li>\n<li><p>Run only scenarios tagged by <code>@someTag</code> or <code>@otherTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"@someTag or @otherTag\"</span>\n</code></pre></li>\n<li><p>Run only scenarios not tagged by <code>@someTag</code></p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin -- --tags <span class=\"hljs-string\">\"not @someTag\"</span>\n</code></pre></li>\n</ul>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting--tips\"></a><a href=\"#troubleshooting--tips\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting &amp; Tips</h2>\n<p>In order to make cucumber steps autosuggestion work properly in JetBrains tools, make sure your project is <code>ECMAScript 6</code> compatible and you have <code>cucumberjs</code> plugin installed.\nDue to non-resolved issue in Jetbrains editors (<a href=\"https://youtrack.jetbrains.com/issue/WEB-11505\">see here</a>) we'll have to do one more step:</p>\n<p>Go to <code>step_definitions</code> directory</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-built_in\">cd</span> step_definitions\n</code></pre>\n<p>Paste this code into terminal and restart your IDE:</p>\n<p>For Linux/MacOs:</p>\n<pre><code class=\"hljs css language-bash\">ln -s ../node_modules/kakunin/src/step_definitions/elements.ts kakunin-elements.ts\nln -s ../node_modules/kakunin/src/step_definitions/debug.ts kakunin-debug.ts\nln -s ../node_modules/kakunin/src/step_definitions/file.ts kakunin-file.ts\nln -s ../node_modules/kakunin/src/step_definitions/form.ts kakunin-form.ts\nln -s ../node_modules/kakunin/src/step_definitions/email.ts kakunin-email.ts\nln -s ../node_modules/kakunin/src/step_definitions/generators.ts kakunin-generators.ts\nln -s ../node_modules/kakunin/src/step_definitions/navigation.ts kakunin-navigation.ts \nln -s ../node_modules/kakunin/src/step_definitions/performance.ts kakunin-performance.ts \n</code></pre>\n<p>For Windows 8+: (you have to do this as administrator)</p>\n<pre><code class=\"hljs css language-bash\">mklink kakunin-elements.ts ../node_modules/kakunin/src/step_definitions/elements.ts\nmklink kakunin-debug.ts ../node_modules/kakunin/src/step_definitions/debug.ts \nmklink kakunin-file.ts ../node_modules/kakunin/src/step_definitions/file.ts \nmklink kakunin-form.ts ../node_modules/kakunin/src/step_definitions/form.ts \nmklink kakunin-email.ts ../node_modules/kakunin/src/step_definitions/email.ts\nmklink kakunin-generators.ts ../node_modules/kakunin/src/step_definitions/generators.ts \nmklink kakunin-navigation.ts ../node_modules/kakunin/src/step_definitions/navigation.ts \nmklink kakunin-performance.ts ../node_modules/kakunin/src/step_definitions/performance.ts \n</code></pre>\n<p>Keep in mind that <code>mklink</code> is not available in older Windows distributions.</p>\n<p>This will create symlinks inside <code>step_definitions</code> directory and make <code>cucumberjs</code> plugin recognize kakunin built-in steps.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/quickstart\"><span class=\"arrow-prev\">← </span><span>Quick start</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/configuration\"><span>Configuration</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#about-kakunin\">About Kakunin</a></li><li><a href=\"#installation\">Installation</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#commands\">Commands</a></li><li><a href=\"#troubleshooting--tips\">Troubleshooting &amp; Tips</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/matchers/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Matchers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Matchers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Matchers</h1></header><article><div><span><p>Matchers allows you to check if a element content matches your expectation.</p>\n<p>For example you can check if a value has a specified pattern or if a button is clickable.</p>\n<p>Using matcher is very straightforward, for example: <code>f:isClickable</code>.</p>\n<p>Matchers can be used in most of the steps related to checking content (with exception of checking form values).</p>\n<p>Kakunin comes with a set of built in matchers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"visibility-matcher\"></a><a href=\"#visibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Visibility matcher</h2>\n<p><code>f:isVisible</code> - checks if element is visible (must be in viewport and cannot be hidden behind any other element)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"invisibility-matcher\"></a><a href=\"#invisibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Invisibility matcher</h2>\n<p><code>f:isNotVisible</code> - checks if element is not visible</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"present-matcher\"></a><a href=\"#present-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Present matcher</h2>\n<p><code>f:isPresent</code> - checks if element is in html code (does not have to be visible)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"clickable-matcher\"></a><a href=\"#clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clickable matcher</h2>\n<p><code>f:isClickable</code> - checks if element is clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"not-clickable-matcher\"></a><a href=\"#not-clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Not clickable matcher</h2>\n<p><code>f:isNotClickable</code> - checks if element is not clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"attribute-matcher\"></a><a href=\"#attribute-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attribute matcher</h2>\n<p><code>attribute:attributeName:regexName</code> - allows to check if element has attribute with a name specified by <code>attributeName</code> and it has to\nhave a format passing <code>regexName</code></p>\n<p>For example, if there is an element:</p>\n<p><code>&lt;p custom-attribute=&quot;123123&quot;&gt;some value&lt;/p&gt;</code></p>\n<p>you can check if attribute is an number by running: <code>attribute:custom-attribute:number</code></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-matcher\"></a><a href=\"#regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex matcher</h2>\n<p><code>r:regexName</code> - allows you to run a <code>regexName</code> against a text value of element</p>\n<p>Regexes have to be specified inside <code>regex</code> directory or be a kakunin built ones:</p>\n<p><code>notEmpty</code> - there must be a value\n<code>number</code> - must be a number</p>\n<p>You can add your own matchers. In order to do so please read <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"text-matcher\"></a><a href=\"#text-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Text matcher</h2>\n<p><code>t:text you are looking for</code> - allows you to check if an element contains a expected text</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"current-date-matcher\"></a><a href=\"#current-date-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Current date matcher</h2>\n<p><code>f:currentDate:{format}</code> - allows you to generate current date, <code>{format}</code> is optional, by default <code>DD-MM-YYYY</code></p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/how-it-works\"><span class=\"arrow-prev\">← </span><span>How it works</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/transformers\"><span>Transformers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#visibility-matcher\">Visibility matcher</a></li><li><a href=\"#invisibility-matcher\">Invisibility matcher</a></li><li><a href=\"#present-matcher\">Present matcher</a></li><li><a href=\"#clickable-matcher\">Clickable matcher</a></li><li><a href=\"#not-clickable-matcher\">Not clickable matcher</a></li><li><a href=\"#attribute-matcher\">Attribute matcher</a></li><li><a href=\"#regex-matcher\">Regex matcher</a></li><li><a href=\"#text-matcher\">Text matcher</a></li><li><a href=\"#current-date-matcher\">Current date matcher</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/matchers.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Matchers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Matchers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Matchers allows you to check if a element content matches your expectation.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Matchers</h1></header><article><div><span><p>Matchers allows you to check if a element content matches your expectation.</p>\n<p>For example you can check if a value has a specified pattern or if a button is clickable.</p>\n<p>Using matcher is very straightforward, for example: <code>f:isClickable</code>.</p>\n<p>Matchers can be used in most of the steps related to checking content (with exception of checking form values).</p>\n<p>Kakunin comes with a set of built in matchers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"visibility-matcher\"></a><a href=\"#visibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Visibility matcher</h2>\n<p><code>f:isVisible</code> - checks if element is visible (must be in viewport and cannot be hidden behind any other element)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"invisibility-matcher\"></a><a href=\"#invisibility-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Invisibility matcher</h2>\n<p><code>f:isNotVisible</code> - checks if element is not visible</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"present-matcher\"></a><a href=\"#present-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Present matcher</h2>\n<p><code>f:isPresent</code> - checks if element is in html code (does not have to be visible)</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"clickable-matcher\"></a><a href=\"#clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clickable matcher</h2>\n<p><code>f:isClickable</code> - checks if element is clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"not-clickable-matcher\"></a><a href=\"#not-clickable-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Not clickable matcher</h2>\n<p><code>f:isNotClickable</code> - checks if element is not clickable</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"attribute-matcher\"></a><a href=\"#attribute-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attribute matcher</h2>\n<p><code>attribute:attributeName:regexName</code> - allows to check if element has attribute with a name specified by <code>attributeName</code> and it has to\nhave a format passing <code>regexName</code></p>\n<p>For example, if there is an element:</p>\n<p><code>&lt;p custom-attribute=&quot;123123&quot;&gt;some value&lt;/p&gt;</code></p>\n<p>you can check if attribute is an number by running: <code>attribute:custom-attribute:number</code></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"regex-matcher\"></a><a href=\"#regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Regex matcher</h2>\n<p><code>r:regexName</code> - allows you to run a <code>regexName</code> against a text value of element</p>\n<p>Regexes have to be specified inside <code>regex</code> directory or be a kakunin built ones:</p>\n<p><code>notEmpty</code> - there must be a value\n<code>number</code> - must be a number</p>\n<p>You can add your own matchers. In order to do so please read <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"text-matcher\"></a><a href=\"#text-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Text matcher</h2>\n<p><code>t:text you are looking for</code> - allows you to check if an element contains a expected text</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"current-date-matcher\"></a><a href=\"#current-date-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Current date matcher</h2>\n<p><code>f:currentDate:{format}</code> - allows you to generate current date, <code>{format}</code> is optional, by default <code>DD-MM-YYYY</code></p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/how-it-works\"><span class=\"arrow-prev\">← </span><span>How it works</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/transformers\"><span>Transformers</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#visibility-matcher\">Visibility matcher</a></li><li><a href=\"#invisibility-matcher\">Invisibility matcher</a></li><li><a href=\"#present-matcher\">Present matcher</a></li><li><a href=\"#clickable-matcher\">Clickable matcher</a></li><li><a href=\"#not-clickable-matcher\">Not clickable matcher</a></li><li><a href=\"#attribute-matcher\">Attribute matcher</a></li><li><a href=\"#regex-matcher\">Regex matcher</a></li><li><a href=\"#text-matcher\">Text matcher</a></li><li><a href=\"#current-date-matcher\">Current date matcher</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/parallel-testing/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Parallel testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"There is a possibility to run tests in parallel.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Parallel testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"There is a possibility to run tests in parallel.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Parallel testing</h1></header><article><div><span><p>There is a possibility to run tests in parallel.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-execute\"></a><a href=\"#how-to-execute\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to execute</h2>\n<p>Use a command <code>npm run kakunin -- --parallel &lt;number of instances&gt;</code> where <code>number of instances</code> is a number.</p>\n<p>Example:</p>\n<ul>\n<li><code>npm run kakunin -- --chrome --parallel 2</code></li>\n</ul>\n<p><span style=\"color:red\">Keep in mind that the merged report is available in the <code>reports/report/index.html</code> file. text</span></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"specify-pattern-per-each-instance\"></a><a href=\"#specify-pattern-per-each-instance\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Specify pattern per each instance</h2>\n<ul>\n<li><code>npm run kakunin -- --parallel &lt;number of instances&gt; --pattern &lt;regex to much feature&gt; --pattern &lt;regex to much feature&gt;</code></li>\n</ul>\n<p>Keep in mind that:</p>\n<ul>\n<li>the number given in <code>parallel</code> must be equal to passed <code>patterns</code></li>\n<li><code>&lt;number of instances&gt;</code> is a number of instances of the specified browser</li>\n<li><code>&lt;regex&gt;</code> is a pattern that is used to specify the list of specs that will be executed in each of the instances</li>\n</ul>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h2>\n<ol>\n<li>Running more than one instance in <code>Firefox</code> is not possible now (fix in-progress).</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/headless\"><span class=\"arrow-prev\">← </span><span>Headless</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/performance-testing\"><span>Performance testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#how-to-execute\">How to execute</a></li><li><a href=\"#specify-pattern-per-each-instance\">Specify pattern per each instance</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/parallel-testing.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Parallel testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"There is a possibility to run tests in parallel.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Parallel testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"There is a possibility to run tests in parallel.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Parallel testing</h1></header><article><div><span><p>There is a possibility to run tests in parallel.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-execute\"></a><a href=\"#how-to-execute\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to execute</h2>\n<p>Use a command <code>npm run kakunin -- --parallel &lt;number of instances&gt;</code> where <code>number of instances</code> is a number.</p>\n<p>Example:</p>\n<ul>\n<li><code>npm run kakunin -- --chrome --parallel 2</code></li>\n</ul>\n<p><span style=\"color:red\">Keep in mind that the merged report is available in the <code>reports/report/index.html</code> file. text</span></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"specify-pattern-per-each-instance\"></a><a href=\"#specify-pattern-per-each-instance\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Specify pattern per each instance</h2>\n<ul>\n<li><code>npm run kakunin -- --parallel &lt;number of instances&gt; --pattern &lt;regex to much feature&gt; --pattern &lt;regex to much feature&gt;</code></li>\n</ul>\n<p>Keep in mind that:</p>\n<ul>\n<li>the number given in <code>parallel</code> must be equal to passed <code>patterns</code></li>\n<li><code>&lt;number of instances&gt;</code> is a number of instances of the specified browser</li>\n<li><code>&lt;regex&gt;</code> is a pattern that is used to specify the list of specs that will be executed in each of the instances</li>\n</ul>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h2>\n<ol>\n<li>Running more than one instance in <code>Firefox</code> is not possible now (fix in-progress).</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/headless\"><span class=\"arrow-prev\">← </span><span>Headless</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/performance-testing\"><span>Performance testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#how-to-execute\">How to execute</a></li><li><a href=\"#specify-pattern-per-each-instance\">Specify pattern per each instance</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/performance-testing/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Performance testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Performance testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Performance testing</h1></header><article><div><span><p>Performance testing is possible thanks to <code>browsermob-proxy</code>.</p>\n<p>It saves all data from network tab (Google Chrome console) which is generated during the test.</p>\n<p>There is a possibility to compare <code>TTFB</code> value with a maximum given one.</p>\n<p><code>TTFB</code> (Time to first byte) measures the duration from the client making an HTTP request to the first byte of a response being received by the client's browser.</p>\n<p>More details can be found in documentation - <code>Built-in steps</code> section.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"what-needs-to-be-done\"></a><a href=\"#what-needs-to-be-done\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What needs to be done?</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"get-started\"></a><a href=\"#get-started\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get started</h2>\n<ol>\n<li><p>Download <code>browsermob-proxy</code> from <code>https://github.com/lightbody/browsermob-proxy</code></p></li>\n<li><p>Navigate in terminal to the catalog</p></li>\n<li><p>Use following command to start the REST API</p></li>\n</ol>\n<pre><code class=\"hljs\">./browsermob-proxy -port <span class=\"hljs-number\">8887</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ol>\n<li>Add <code>browsermob-proxy</code> configuration to <code>kakunin.conf.js</code></li>\n</ol>\n<p>You can use one of the following methods to configure browsermob-proxy:</p>\n<ul>\n<li><p><code>npm run kakunin init -- --advanced</code> and go through the process</p></li>\n<li><p>or add it manually to the config file:</p></li>\n</ul>\n<pre><code class=\"hljs css language-javascript\">    <span class=\"hljs-string\">\"browserMob\"</span>: {\n      <span class=\"hljs-string\">\"serverPort\"</span>: <span class=\"hljs-number\">8887</span>,\n      <span class=\"hljs-string\">\"port\"</span>: <span class=\"hljs-number\">8888</span>,\n      <span class=\"hljs-string\">\"host\"</span>: <span class=\"hljs-string\">\"localhost\"</span>\n    }\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h2>\n<ol>\n<li><p><code>performance steps</code> must be used in the scenario where you are testing performance</p></li>\n<li><p>Scenario must have a tag <code>@performance</code></p></li>\n<li><p>Run tests with special parameter:</p></li>\n</ol>\n<pre><code class=\"hljs\">npm <span class=\"hljs-built_in\">run</span> kakunin <span class=\"hljs-comment\">-- --performance</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"results\"></a><a href=\"#results\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Results</h2>\n<ol>\n<li><code>.har</code> files are saved in catalog <code>reports/performance/*.har</code></li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/parallel-testing\"><span class=\"arrow-prev\">← </span><span>Parallel testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/docker\"><span>Docker</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#get-started\">Get started</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#results\">Results</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/performance-testing.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Performance testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Performance testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Performance testing</h1></header><article><div><span><p>Performance testing is possible thanks to <code>browsermob-proxy</code>.</p>\n<p>It saves all data from network tab (Google Chrome console) which is generated during the test.</p>\n<p>There is a possibility to compare <code>TTFB</code> value with a maximum given one.</p>\n<p><code>TTFB</code> (Time to first byte) measures the duration from the client making an HTTP request to the first byte of a response being received by the client's browser.</p>\n<p>More details can be found in documentation - <code>Built-in steps</code> section.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"what-needs-to-be-done\"></a><a href=\"#what-needs-to-be-done\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What needs to be done?</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"get-started\"></a><a href=\"#get-started\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get started</h2>\n<ol>\n<li><p>Download <code>browsermob-proxy</code> from <code>https://github.com/lightbody/browsermob-proxy</code></p></li>\n<li><p>Navigate in terminal to the catalog</p></li>\n<li><p>Use following command to start the REST API</p></li>\n</ol>\n<pre><code class=\"hljs\">./browsermob-proxy -port <span class=\"hljs-number\">8887</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ol>\n<li>Add <code>browsermob-proxy</code> configuration to <code>kakunin.conf.js</code></li>\n</ol>\n<p>You can use one of the following methods to configure browsermob-proxy:</p>\n<ul>\n<li><p><code>npm run kakunin init -- --advanced</code> and go through the process</p></li>\n<li><p>or add it manually to the config file:</p></li>\n</ul>\n<pre><code class=\"hljs css language-javascript\">    <span class=\"hljs-string\">\"browserMob\"</span>: {\n      <span class=\"hljs-string\">\"serverPort\"</span>: <span class=\"hljs-number\">8887</span>,\n      <span class=\"hljs-string\">\"port\"</span>: <span class=\"hljs-number\">8888</span>,\n      <span class=\"hljs-string\">\"host\"</span>: <span class=\"hljs-string\">\"localhost\"</span>\n    }\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h2>\n<ol>\n<li><p><code>performance steps</code> must be used in the scenario where you are testing performance</p></li>\n<li><p>Scenario must have a tag <code>@performance</code></p></li>\n<li><p>Run tests with special parameter:</p></li>\n</ol>\n<pre><code class=\"hljs\">npm <span class=\"hljs-built_in\">run</span> kakunin <span class=\"hljs-comment\">-- --performance</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"results\"></a><a href=\"#results\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Results</h2>\n<ol>\n<li><code>.har</code> files are saved in catalog <code>reports/performance/*.har</code></li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/parallel-testing\"><span class=\"arrow-prev\">← </span><span>Parallel testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/docker\"><span>Docker</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#get-started\">Get started</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#results\">Results</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/quickstart/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Quick start · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Quick start · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Quick start</h1></header><article><div><span><p>As a quick demonstration of the framework let's test the\n<a href=\"http://todomvc.com/examples/react/#/\">React variant of TodoMVC</a> project.\nOf course other testing other frameworks is possible, you can try it\nby yourself!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"install-packages\"></a><a href=\"#install-packages\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install packages</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project and enter it</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-variable\">$mkdir</span> my_project\n<span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env kakunin --save\n</code></pre>\n<p>Inside <code>package.json</code> file add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-js\">...\n<span class=\"hljs-string\">\"scripts\"</span>: {\n  <span class=\"hljs-string\">\"kakunin\"</span>: <span class=\"hljs-string\">\"cross-env NODE_ENV=prod kakunin\"</span>\n},\n...\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configure-kakunin\"></a><a href=\"#configure-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure Kakunin</h2>\n<p>Run initialization command</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>Answer literally few questions:</p>\n<pre><code class=\"hljs css language-text\">What kind of application would you like to test? : otherWeb\n        \nWhat is base url? [http://localhost:3000]: http://todomvc.com\n           \nWhat kind of email service would you like to use?: none\n</code></pre>\n<p>And you're set! Now let's write some test!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"test-the-app\"></a><a href=\"#test-the-app\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the app</h2>\n<p>Create a page object that will contain instructions on how to locate elements in the projects.\nCreate a file <code>pages/main.js</code>:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MainPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n\n        <span class=\"hljs-comment\">// define the main url for the page</span>\n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/examples/react/#/'</span>;\n\n        <span class=\"hljs-comment\">// whole form tag</span>\n        <span class=\"hljs-keyword\">this</span>.addTodoForm = $(<span class=\"hljs-string\">'.todoapp'</span>);\n\n        <span class=\"hljs-comment\">// input field</span>\n        <span class=\"hljs-keyword\">this</span>.todoInput = $(<span class=\"hljs-string\">'input.new-todo'</span>);\n\n        <span class=\"hljs-comment\">// list of currently added todos</span>\n        <span class=\"hljs-keyword\">this</span>.todos = $$(<span class=\"hljs-string\">'.todo-list .view'</span>);\n        <span class=\"hljs-keyword\">this</span>.todoLabel = by.css(<span class=\"hljs-string\">'label'</span>);\n\n        <span class=\"hljs-comment\">// first todo item in a list</span>\n        <span class=\"hljs-keyword\">this</span>.firstTodoItem = <span class=\"hljs-keyword\">this</span>.todos.get(<span class=\"hljs-number\">0</span>);\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MainPage;\n</code></pre>\n<p>Now that we have prepared the locators, we can start writing our test. Let's test adding new todo item.</p>\n<p>Create a file named: <code>features/adding_todo.feature</code> with the following contents:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 1\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n\n</code></pre>\n<p>And that's it! All you have to do now is to run the test and watch the magic happens ;)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<p>The tests may run quite fast so you might not been able to see that it\nreally works as expected. To check if the todo items has been really\nadded to the list, let's use a simple hack - let's pause the running\ntest right after the todo has been added.</p>\n<p>To do that, let's upgrade our Scenario. Update the file:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> Another todo item! </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 2\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n        <span class=\"hljs-keyword\">Then</span> I wait for <span class=\"hljs-string\">\"5\"</span> seconds\n\n</code></pre>\n<p>As you can see, we've added 1 new step that waits for a second before\n&quot;pressing&quot; the <code>enter</code> key. We've also added a second todo item with\na short pause at the end of the test so you can see the changes.</p>\n<p>If you want to see what can we do more with the TodoMVC project, take a look\nat the <code>example</code> dir, where you'll find a complete set of test for the project.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-next button\" href=\"/Kakunin/docs/next/index\"><span>Getting started</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#install-packages\">Install packages</a></li><li><a href=\"#configure-kakunin\">Configure Kakunin</a></li><li><a href=\"#test-the-app\">Test the app</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/quickstart.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Quick start · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Quick start · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Quick start</h1></header><article><div><span><p>As a quick demonstration of the framework let's test the\n<a href=\"http://todomvc.com/examples/react/#/\">React variant of TodoMVC</a> project.\nOf course other testing other frameworks is possible, you can try it\nby yourself!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"install-packages\"></a><a href=\"#install-packages\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install packages</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project and enter it</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-variable\">$mkdir</span> my_project\n<span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env kakunin --save\n</code></pre>\n<p>Inside <code>package.json</code> file add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-js\">...\n<span class=\"hljs-string\">\"scripts\"</span>: {\n  <span class=\"hljs-string\">\"kakunin\"</span>: <span class=\"hljs-string\">\"cross-env NODE_ENV=prod kakunin\"</span>\n},\n...\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configure-kakunin\"></a><a href=\"#configure-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure Kakunin</h2>\n<p>Run initialization command</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>Answer literally few questions:</p>\n<pre><code class=\"hljs css language-text\">What kind of application would you like to test? : otherWeb\n        \nWhat is base url? [http://localhost:3000]: http://todomvc.com\n           \nWhat kind of email service would you like to use?: none\n</code></pre>\n<p>And you're set! Now let's write some test!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"test-the-app\"></a><a href=\"#test-the-app\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the app</h2>\n<p>Create a page object that will contain instructions on how to locate elements in the projects.\nCreate a file <code>pages/main.js</code>:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MainPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n\n        <span class=\"hljs-comment\">// define the main url for the page</span>\n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/examples/react/#/'</span>;\n\n        <span class=\"hljs-comment\">// whole form tag</span>\n        <span class=\"hljs-keyword\">this</span>.addTodoForm = $(<span class=\"hljs-string\">'.todoapp'</span>);\n\n        <span class=\"hljs-comment\">// input field</span>\n        <span class=\"hljs-keyword\">this</span>.todoInput = $(<span class=\"hljs-string\">'input.new-todo'</span>);\n\n        <span class=\"hljs-comment\">// list of currently added todos</span>\n        <span class=\"hljs-keyword\">this</span>.todos = $$(<span class=\"hljs-string\">'.todo-list .view'</span>);\n        <span class=\"hljs-keyword\">this</span>.todoLabel = by.css(<span class=\"hljs-string\">'label'</span>);\n\n        <span class=\"hljs-comment\">// first todo item in a list</span>\n        <span class=\"hljs-keyword\">this</span>.firstTodoItem = <span class=\"hljs-keyword\">this</span>.todos.get(<span class=\"hljs-number\">0</span>);\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MainPage;\n</code></pre>\n<p>Now that we have prepared the locators, we can start writing our test. Let's test adding new todo item.</p>\n<p>Create a file named: <code>features/adding_todo.feature</code> with the following contents:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 1\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n\n</code></pre>\n<p>And that's it! All you have to do now is to run the test and watch the magic happens ;)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<p>The tests may run quite fast so you might not been able to see that it\nreally works as expected. To check if the todo items has been really\nadded to the list, let's use a simple hack - let's pause the running\ntest right after the todo has been added.</p>\n<p>To do that, let's upgrade our Scenario. Update the file:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> Another todo item! </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 2\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n        <span class=\"hljs-keyword\">Then</span> I wait for <span class=\"hljs-string\">\"5\"</span> seconds\n\n</code></pre>\n<p>As you can see, we've added 1 new step that waits for a second before\n&quot;pressing&quot; the <code>enter</code> key. We've also added a second todo item with\na short pause at the end of the test so you can see the changes.</p>\n<p>If you want to see what can we do more with the TodoMVC project, take a look\nat the <code>example</code> dir, where you'll find a complete set of test for the project.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-next button\" href=\"/Kakunin/docs/next/index\"><span>Getting started</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#install-packages\">Install packages</a></li><li><a href=\"#configure-kakunin\">Configure Kakunin</a></li><li><a href=\"#test-the-app\">Test the app</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-debug/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Debug · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps for debugging application:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Debug · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps for debugging application:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Debug</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-for-debugging-application\"></a><a href=\"#steps-for-debugging-application\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps for debugging application:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-pause\"></a><a href=\"#i-pause\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I pause</code></h2>\n<p>Pauses tests execution and allows to continue manually by pressing combination of <code>ctrl+c</code> inside terminal.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-seconds-seconds\"></a><a href=\"#i-wait-for-seconds-seconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:seconds&quot; seconds</code></h2>\n<p>Waits with execution of next step for an amount provided by parameter <code>:seconds</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-start-performance-monitor-mode\"></a><a href=\"#i-start-performance-monitor-mode\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I start performance monitor mode</code></h2>\n<p>It starts performance monitor mode.</p>\n<p>Keep in mind that REST API must be started on the port which must configured in <code>kakunin.conf.js</code> - <code>serverPort: 8887</code>.</p>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-save-performance-report-file-as-filename\"></a><a href=\"#i-save-performance-report-file-as-filename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I save performance report file as &quot;fileName&quot;</code></h2>\n<p>It saves <code>.har</code> file with a name <code>fileName</code> in <code>reports/performance</code> catalog.</p>\n<p>For example: <code>exampleReport-1511470954552.har</code></p>\n<p>Data is generated during the test - network tab in Chrome Chrome console.</p>\n<p>Keep in mind:</p>\n<ul>\n<li><p><code>I start performance monitor mode</code> must be used before this step</p></li>\n<li><p><code>browserMob.port</code> must be configured in <code>kakunin.conf.js</code></p></li>\n<li><p><code>browserMob.host</code> must be configured in <code>kakunin.conf.js</code></p></li>\n</ul>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"></a><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></h2>\n<p>It compares every <code>TTFB</code> timing value from previously saved <code>.har</code> report with a <code>maxTiming</code> value.</p>\n<p>Slow requests are listed in your terminal in red colour.</p>\n<p>Keep in mind that <code>I start performance monitor mode</code> and <code>I save performance report file as &quot;fileName&quot;</code> steps must be executed before this one!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-generators\"><span class=\"arrow-prev\">← </span><span>Generators</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-rest\"><span>Rest api</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-pause\"><code>I pause</code></a></li><li><a href=\"#i-wait-for-seconds-seconds\"><code>I wait for &quot;:seconds&quot; seconds</code></a></li><li><a href=\"#i-start-performance-monitor-mode\"><code>I start performance monitor mode</code></a></li><li><a href=\"#i-save-performance-report-file-as-filename\"><code>I save performance report file as &quot;fileName&quot;</code></a></li><li><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-debug.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Debug · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps for debugging application:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Debug · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps for debugging application:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Debug</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-for-debugging-application\"></a><a href=\"#steps-for-debugging-application\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps for debugging application:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-pause\"></a><a href=\"#i-pause\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I pause</code></h2>\n<p>Pauses tests execution and allows to continue manually by pressing combination of <code>ctrl+c</code> inside terminal.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-seconds-seconds\"></a><a href=\"#i-wait-for-seconds-seconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:seconds&quot; seconds</code></h2>\n<p>Waits with execution of next step for an amount provided by parameter <code>:seconds</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-start-performance-monitor-mode\"></a><a href=\"#i-start-performance-monitor-mode\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I start performance monitor mode</code></h2>\n<p>It starts performance monitor mode.</p>\n<p>Keep in mind that REST API must be started on the port which must configured in <code>kakunin.conf.js</code> - <code>serverPort: 8887</code>.</p>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-save-performance-report-file-as-filename\"></a><a href=\"#i-save-performance-report-file-as-filename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I save performance report file as &quot;fileName&quot;</code></h2>\n<p>It saves <code>.har</code> file with a name <code>fileName</code> in <code>reports/performance</code> catalog.</p>\n<p>For example: <code>exampleReport-1511470954552.har</code></p>\n<p>Data is generated during the test - network tab in Chrome Chrome console.</p>\n<p>Keep in mind:</p>\n<ul>\n<li><p><code>I start performance monitor mode</code> must be used before this step</p></li>\n<li><p><code>browserMob.port</code> must be configured in <code>kakunin.conf.js</code></p></li>\n<li><p><code>browserMob.host</code> must be configured in <code>kakunin.conf.js</code></p></li>\n</ul>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"></a><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></h2>\n<p>It compares every <code>TTFB</code> timing value from previously saved <code>.har</code> report with a <code>maxTiming</code> value.</p>\n<p>Slow requests are listed in your terminal in red colour.</p>\n<p>Keep in mind that <code>I start performance monitor mode</code> and <code>I save performance report file as &quot;fileName&quot;</code> steps must be executed before this one!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-generators\"><span class=\"arrow-prev\">← </span><span>Generators</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-rest\"><span>Rest api</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-pause\"><code>I pause</code></a></li><li><a href=\"#i-wait-for-seconds-seconds\"><code>I wait for &quot;:seconds&quot; seconds</code></a></li><li><a href=\"#i-start-performance-monitor-mode\"><code>I start performance monitor mode</code></a></li><li><a href=\"#i-save-performance-report-file-as-filename\"><code>I save performance report file as &quot;fileName&quot;</code></a></li><li><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-elements/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Elements · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with elements:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Elements · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with elements:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Elements</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-elements\"></a><a href=\"#steps-used-to-interact-with-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with elements:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll through infinite scroll mechanism.</p>\n<p>The <code>:elementName</code> is a name of a selector for loading trigger.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-expectedconditionname-of-the-elementname-element\"></a><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></h2>\n<p>Waits till element <code>:elementName</code> from <code>this.currentPage</code> meets criteria specified by <code>:expectedConditionName</code>.</p>\n<p>You can use any of the Protractor's expected condition:</p>\n<ul>\n<li><code>visibilityOf</code></li>\n<li><code>invisibilityOf</code></li>\n</ul>\n<p>etc.</p>\n<p>Read more in Protractor's API documentation.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-the-elementname-element-to-disappear\"></a><a href=\"#i-wait-for-the-elementname-element-to-disappear\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for the &quot;:elementName&quot; element to disappear</code></h2>\n<p>Waits till element <code>:elementName</code> disappears.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-scroll-to-the-elementname-element\"></a><a href=\"#i-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Scrolls to element <code>:elementName</code> of <code>this.currentPage</code>. The element will be on bottom of the page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element-1\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll till <code>:elementName</code> is visible. Useful for infinite scrolling functionality.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-press-the-keyname-key\"></a><a href=\"#i-press-the-keyname-key\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I press the &quot;:keyName&quot; key</code></h2>\n<p>Performs a key press operation on <code>:keyName</code> key.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-click-the-elementname-element\"></a><a href=\"#i-click-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I click the &quot;:elementName&quot; element</code></h2>\n<p>Performs a click action on element <code>:elementName</code> from `this.currentPage'</p>\n<p>The child element must be specified by <code>:elementName</code> and must be available in <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the text from element <code>:elementName</code> of <code>this.currentPage</code> under the <code>:variableName</code> so you can use it later.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-update-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Updates the variable <code>:variableName</code> value by value from element <code>:elementName</code> of <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the part of the element <code>:elementName</code> text, that matches the <code>:matchingRegex</code> under the <code>:variableName</code> for later use.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-visible\"></a><a href=\"#the-elementname-element-is-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is visible</code></h2>\n<p>Checks if element <code>:elementName</code> is visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-not-visible\"></a><a href=\"#the-elementname-element-is-not-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is not visible</code></h2>\n<p>Checks if element <code>:elementName</code> is available in HTML DOM but is not visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-disabled\"></a><a href=\"#the-elementname-element-is-disabled\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot; element is disabled</code></h2>\n<p>Checks if element is disabled</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-table-tablerow-rows-as-variablename-with-columns\"></a><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></h2>\n<p>Allows to store a row specified columns from a table <code>:tableRow</code> and save it under <code>:variableName</code> as an array of objects.</p>\n<p>This step requires a table of columns elements, for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I store table <span class=\"hljs-string\">\"someRow\"</span> rows as <span class=\"hljs-string\">\"someVariable\"</span> with columns:\n  |<span class=\"hljs-string\"> firstName </span>|\n  |<span class=\"hljs-string\"> lastName  </span>|\n  |<span class=\"hljs-string\"> id        </span>|\n</code></pre>\n<p>In order to make it work there must be not only array element <code>this.someRow = $$('.rows')</code> in <code>this.currentPage</code>, but also\nelement <code>this.firstName = $('.firstName');</code> and so on.</p>\n<p>The result of this step is an array of:</p>\n<pre><code class=\"hljs css language-javascript\">[\n  [\n    <span class=\"hljs-string\">'firsRowFirstNameValue'</span>,\n    <span class=\"hljs-string\">'firsRowLastNameValue'</span>\n    <span class=\"hljs-string\">'firsRowIdValue'</span>\n  ]\n  ...\n]\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-following-elements-in-table-elementname\"></a><a href=\"#there-are-following-elements-in-table-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are following elements in table &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content.</p>\n<p>This steps allows you to specify an array of child elements that will be checked against expected values.</p>\n<p>For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are following elements in table <span class=\"hljs-string\">\"myTable\"</span>:\n  |<span class=\"hljs-string\"> id  </span>|<span class=\"hljs-string\"> firstName </span>|<span class=\"hljs-string\"> lastName </span>|\n  |<span class=\"hljs-string\"> t:1 </span>|<span class=\"hljs-string\"> t:Adam    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n  |<span class=\"hljs-string\"> t:2 </span>|<span class=\"hljs-string\"> t:John    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n</code></pre>\n<p>First row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.</p>\n<p>This step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.</p>\n<p>We can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-following-elements-for-element-elementname\"></a><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>Allows to check if a number of elements is the one that we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are <span class=\"hljs-string\">\"equal 5\"</span> following elements for element <span class=\"hljs-string\">\"myList\"</span>:\n  |<span class=\"hljs-string\"> viewButton </span>|<span class=\"hljs-string\"> f:isClickable </span>|\n  |<span class=\"hljs-string\"> id         </span>|<span class=\"hljs-string\"> r:idRegex     </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.viewButton = $('button.viewButton');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-elementname-dropdown-list-elements-with-following-options\"></a><a href=\"#there-are-elementname-dropdown-list-elements-with-following-options\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;:elementName&quot; dropdown list elements with following options:</code></h2>\n<p>Allows to check if there is exact match to options provided in table for option selector.</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">select</span> <span class=\"hljs-attr\">name</span>=<span class=\"hljs-string\">\"list\"</span> <span class=\"hljs-attr\">id</span>=<span class=\"hljs-string\">\"personlist\"</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option</span> <span class=\"hljs-attr\">value</span>=<span class=\"hljs-string\">\"1\"</span>&gt;</span>Person 1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">option</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option</span> <span class=\"hljs-attr\">value</span>=<span class=\"hljs-string\">\"2\"</span>&gt;</span>Person 2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">option</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option</span> <span class=\"hljs-attr\">value</span>=<span class=\"hljs-string\">\"3\"</span>&gt;</span>Person 3<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">option</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option</span> <span class=\"hljs-attr\">value</span>=<span class=\"hljs-string\">\"4\"</span>&gt;</span>Person 4<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">option</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">select</span>&gt;</span>\n</code></pre>\n<p>For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are <span class=\"hljs-string\">\"personOption\"</span> dropdown list elements with following options:\n  |<span class=\"hljs-string\"> Person 1      </span>|\n  |<span class=\"hljs-string\"> Person 2      </span>|\n  |<span class=\"hljs-string\"> Person 3      </span>|\n  |<span class=\"hljs-string\"> Person 4      </span>|\n</code></pre>\n<p>The element must be for example:<br>\n<code>this.personOption = this.personForm.$$('option');</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-value-matcher\"></a><a href=\"#there-is-element-elementname-with-value-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> has a value that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-containing-matcher-text\"></a><a href=\"#there-is-element-elementname-containing-matcher-text\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></h2>\n<p>Allows to check if <code>:elementName</code> contains a text that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-matching-matcher-matcher\"></a><a href=\"#there-is-element-elementname-matching-matcher-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></h2>\n<p>Allows to check if <code>:elementName</code> matches the given type of <code>:matcher</code>. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there is element <span class=\"hljs-string\">\"button\"</span> matching <span class=\"hljs-string\">\"isClickable\"</span> matcher\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-regex-matcher\"></a><a href=\"#there-is-element-elementname-with-regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> matches given type of regex. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there is element <span class=\"hljs-string\">\"input\"</span> with regex <span class=\"hljs-string\">\"notEmpty\"</span>\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-value-matchername\"></a><a href=\"#there-is-no-element-elementname-with-value-matchername\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></h2>\n<p>Allows to check if there is no <code>:elementName</code> that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-containing-matcher-text\"></a><a href=\"#there-is-no-element-elementname-containing-matcher-text\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></h2>\n<p>Allows to check if <code>:elementName</code> doesn't contain a text that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-matching-matcher-matcher\"></a><a href=\"#there-is-no-element-elementname-matching-matcher-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></h2>\n<p>Allows to check if <code>:elementName</code> is not matching the given type of <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-regex-matcher\"></a><a href=\"#there-is-no-element-elementname-with-regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> is not matching given type of regex.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-elementname-elements\"></a><a href=\"#there-are-numberexpression-elementname-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></h2>\n<p>Allows to check if a number of <code>:elementName</code> elements is the same as we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p><code>:elementName</code> should be specified as an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"every-elementname-element-should-have-the-same-value-for-element-columnelementname\"></a><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></h2>\n<p>Allows to check if every row defined by <code>:elementName</code> has the same value for a column <code>:columnElementName</code>.</p>\n<p><code>:elementName</code> must be an array of elements</p>\n<p><code>:columnElementName</code> must be an element, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code> and we can specify column element\n<code>this.myColumn = $('td');</code>. This allows us to write:</p>\n<p><code>every &quot;myElement&quot; element should have the same value for element &quot;myColumn&quot;</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should have an item with values:</code></h2>\n<p>Allows to check if any of the child elements of <code>:elementName</code> have a specified content (one matching element is enough). Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:1 </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-not-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-not-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should not have an item with values:</code></h2>\n<p>Allows to check if the child elements of <code>:elementName</code> have a different content than that given in the table. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:does-not-exist </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-drag-elementdrag-element-and-drop-over-elementdrop-element\"></a><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></h2>\n<p>Clicks on <code>:elementDrag</code> and moves it onto <code>:elementDrop</code> while left mouse button is pressed, and then release it.</p>\n<p>Note: This step is not working on HTML5!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-forms\"><span class=\"arrow-prev\">← </span><span>Forms</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-files\"><span>Files</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-infinitely-scroll-to-the-elementname-element\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\"><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-the-elementname-element-to-disappear\"><code>I wait for the &quot;:elementName&quot; element to disappear</code></a></li><li><a href=\"#i-scroll-to-the-elementname-element\"><code>I scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-press-the-keyname-key\"><code>I press the &quot;:keyName&quot; key</code></a></li><li><a href=\"#i-click-the-elementname-element\"><code>I click the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\"><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#the-elementname-element-is-visible\"><code>the &quot;:elementName&quot;&quot; element is visible</code></a></li><li><a href=\"#the-elementname-element-is-not-visible\"><code>the &quot;:elementName&quot;&quot; element is not visible</code></a></li><li><a href=\"#the-elementname-element-is-disabled\"><code>the &quot;:elementName&quot; element is disabled</code></a></li><li><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\"><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></a></li><li><a href=\"#there-are-following-elements-in-table-elementname\"><code>there are following elements in table &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\"><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-are-elementname-dropdown-list-elements-with-following-options\"><code>there are &quot;:elementName&quot; dropdown list elements with following options:</code></a></li><li><a href=\"#there-is-element-elementname-with-value-matcher\"><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-element-elementname-containing-matcher-text\"><code>there is element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></a></li><li><a href=\"#there-is-element-elementname-matching-matcher-matcher\"><code>there is element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></a></li><li><a href=\"#there-is-element-elementname-with-regex-matcher\"><code>there is element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-with-value-matchername\"><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-containing-matcher-text\"><code>there is no element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></a></li><li><a href=\"#there-is-no-element-elementname-matching-matcher-matcher\"><code>there is no element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></a></li><li><a href=\"#there-is-no-element-elementname-with-regex-matcher\"><code>there is no element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></a></li><li><a href=\"#there-are-numberexpression-elementname-elements\"><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></a></li><li><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\"><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></a></li><li><a href=\"#the-element-elementname-should-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should have an item with values:</code></a></li><li><a href=\"#the-element-elementname-should-not-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should not have an item with values:</code></a></li><li><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\"><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-elements.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Elements · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with elements:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Elements · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with elements:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Elements</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-elements\"></a><a href=\"#steps-used-to-interact-with-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with elements:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll through infinite scroll mechanism.</p>\n<p>The <code>:elementName</code> is a name of a selector for loading trigger.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-expectedconditionname-of-the-elementname-element\"></a><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></h2>\n<p>Waits till element <code>:elementName</code> from <code>this.currentPage</code> meets criteria specified by <code>:expectedConditionName</code>.</p>\n<p>You can use any of the Protractor's expected condition:</p>\n<ul>\n<li><code>visibilityOf</code></li>\n<li><code>invisibilityOf</code></li>\n</ul>\n<p>etc.</p>\n<p>Read more in Protractor's API documentation.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-the-elementname-element-to-disappear\"></a><a href=\"#i-wait-for-the-elementname-element-to-disappear\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for the &quot;:elementName&quot; element to disappear</code></h2>\n<p>Waits till element <code>:elementName</code> disappears.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-scroll-to-the-elementname-element\"></a><a href=\"#i-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Scrolls to element <code>:elementName</code> of <code>this.currentPage</code>. The element will be on bottom of the page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element-1\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll till <code>:elementName</code> is visible. Useful for infinite scrolling functionality.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-press-the-keyname-key\"></a><a href=\"#i-press-the-keyname-key\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I press the &quot;:keyName&quot; key</code></h2>\n<p>Performs a key press operation on <code>:keyName</code> key.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-click-the-elementname-element\"></a><a href=\"#i-click-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I click the &quot;:elementName&quot; element</code></h2>\n<p>Performs a click action on element <code>:elementName</code> from `this.currentPage'</p>\n<p>The child element must be specified by <code>:elementName</code> and must be available in <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the text from element <code>:elementName</code> of <code>this.currentPage</code> under the <code>:variableName</code> so you can use it later.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-update-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Updates the variable <code>:variableName</code> value by value from element <code>:elementName</code> of <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the part of the element <code>:elementName</code> text, that matches the <code>:matchingRegex</code> under the <code>:variableName</code> for later use.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-visible\"></a><a href=\"#the-elementname-element-is-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is visible</code></h2>\n<p>Checks if element <code>:elementName</code> is visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-not-visible\"></a><a href=\"#the-elementname-element-is-not-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is not visible</code></h2>\n<p>Checks if element <code>:elementName</code> is available in HTML DOM but is not visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-disabled\"></a><a href=\"#the-elementname-element-is-disabled\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot; element is disabled</code></h2>\n<p>Checks if element is disabled</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-table-tablerow-rows-as-variablename-with-columns\"></a><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></h2>\n<p>Allows to store a row specified columns from a table <code>:tableRow</code> and save it under <code>:variableName</code> as an array of objects.</p>\n<p>This step requires a table of columns elements, for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I store table <span class=\"hljs-string\">\"someRow\"</span> rows as <span class=\"hljs-string\">\"someVariable\"</span> with columns:\n  |<span class=\"hljs-string\"> firstName </span>|\n  |<span class=\"hljs-string\"> lastName  </span>|\n  |<span class=\"hljs-string\"> id        </span>|\n</code></pre>\n<p>In order to make it work there must be not only array element <code>this.someRow = $$('.rows')</code> in <code>this.currentPage</code>, but also\nelement <code>this.firstName = $('.firstName');</code> and so on.</p>\n<p>The result of this step is an array of:</p>\n<pre><code class=\"hljs css language-javascript\">[\n  [\n    <span class=\"hljs-string\">'firsRowFirstNameValue'</span>,\n    <span class=\"hljs-string\">'firsRowLastNameValue'</span>\n    <span class=\"hljs-string\">'firsRowIdValue'</span>\n  ]\n  ...\n]\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-following-elements-in-table-elementname\"></a><a href=\"#there-are-following-elements-in-table-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are following elements in table &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content.</p>\n<p>This steps allows you to specify an array of child elements that will be checked against expected values.</p>\n<p>For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are following elements in table <span class=\"hljs-string\">\"myTable\"</span>:\n  |<span class=\"hljs-string\"> id  </span>|<span class=\"hljs-string\"> firstName </span>|<span class=\"hljs-string\"> lastName </span>|\n  |<span class=\"hljs-string\"> t:1 </span>|<span class=\"hljs-string\"> t:Adam    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n  |<span class=\"hljs-string\"> t:2 </span>|<span class=\"hljs-string\"> t:John    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n</code></pre>\n<p>First row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.</p>\n<p>This step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.</p>\n<p>We can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-following-elements-for-element-elementname\"></a><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>Allows to check if a number of elements is the one that we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are <span class=\"hljs-string\">\"equal 5\"</span> following elements for element <span class=\"hljs-string\">\"myList\"</span>:\n  |<span class=\"hljs-string\"> viewButton </span>|<span class=\"hljs-string\"> f:isClickable </span>|\n  |<span class=\"hljs-string\"> id         </span>|<span class=\"hljs-string\"> r:idRegex     </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.viewButton = $('button.viewButton');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-elementname-dropdown-list-elements-with-following-options\"></a><a href=\"#there-are-elementname-dropdown-list-elements-with-following-options\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;:elementName&quot; dropdown list elements with following options:</code></h2>\n<p>Allows to check if there is exact match to options provided in table for option selector.</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">select</span> <span class=\"hljs-attr\">name</span>=<span class=\"hljs-string\">\"list\"</span> <span class=\"hljs-attr\">id</span>=<span class=\"hljs-string\">\"personlist\"</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option</span> <span class=\"hljs-attr\">value</span>=<span class=\"hljs-string\">\"1\"</span>&gt;</span>Person 1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">option</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option</span> <span class=\"hljs-attr\">value</span>=<span class=\"hljs-string\">\"2\"</span>&gt;</span>Person 2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">option</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option</span> <span class=\"hljs-attr\">value</span>=<span class=\"hljs-string\">\"3\"</span>&gt;</span>Person 3<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">option</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option</span> <span class=\"hljs-attr\">value</span>=<span class=\"hljs-string\">\"4\"</span>&gt;</span>Person 4<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">option</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">select</span>&gt;</span>\n</code></pre>\n<p>For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are <span class=\"hljs-string\">\"personOption\"</span> dropdown list elements with following options:\n  |<span class=\"hljs-string\"> Person 1      </span>|\n  |<span class=\"hljs-string\"> Person 2      </span>|\n  |<span class=\"hljs-string\"> Person 3      </span>|\n  |<span class=\"hljs-string\"> Person 4      </span>|\n</code></pre>\n<p>The element must be for example:<br>\n<code>this.personOption = this.personForm.$$('option');</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-value-matcher\"></a><a href=\"#there-is-element-elementname-with-value-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> has a value that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-containing-matcher-text\"></a><a href=\"#there-is-element-elementname-containing-matcher-text\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></h2>\n<p>Allows to check if <code>:elementName</code> contains a text that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-matching-matcher-matcher\"></a><a href=\"#there-is-element-elementname-matching-matcher-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></h2>\n<p>Allows to check if <code>:elementName</code> matches the given type of <code>:matcher</code>. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there is element <span class=\"hljs-string\">\"button\"</span> matching <span class=\"hljs-string\">\"isClickable\"</span> matcher\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-regex-matcher\"></a><a href=\"#there-is-element-elementname-with-regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> matches given type of regex. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there is element <span class=\"hljs-string\">\"input\"</span> with regex <span class=\"hljs-string\">\"notEmpty\"</span>\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-value-matchername\"></a><a href=\"#there-is-no-element-elementname-with-value-matchername\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></h2>\n<p>Allows to check if there is no <code>:elementName</code> that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-containing-matcher-text\"></a><a href=\"#there-is-no-element-elementname-containing-matcher-text\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></h2>\n<p>Allows to check if <code>:elementName</code> doesn't contain a text that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-matching-matcher-matcher\"></a><a href=\"#there-is-no-element-elementname-matching-matcher-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></h2>\n<p>Allows to check if <code>:elementName</code> is not matching the given type of <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-regex-matcher\"></a><a href=\"#there-is-no-element-elementname-with-regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> is not matching given type of regex.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-elementname-elements\"></a><a href=\"#there-are-numberexpression-elementname-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></h2>\n<p>Allows to check if a number of <code>:elementName</code> elements is the same as we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p><code>:elementName</code> should be specified as an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"every-elementname-element-should-have-the-same-value-for-element-columnelementname\"></a><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></h2>\n<p>Allows to check if every row defined by <code>:elementName</code> has the same value for a column <code>:columnElementName</code>.</p>\n<p><code>:elementName</code> must be an array of elements</p>\n<p><code>:columnElementName</code> must be an element, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code> and we can specify column element\n<code>this.myColumn = $('td');</code>. This allows us to write:</p>\n<p><code>every &quot;myElement&quot; element should have the same value for element &quot;myColumn&quot;</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should have an item with values:</code></h2>\n<p>Allows to check if any of the child elements of <code>:elementName</code> have a specified content (one matching element is enough). Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:1 </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-not-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-not-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should not have an item with values:</code></h2>\n<p>Allows to check if the child elements of <code>:elementName</code> have a different content than that given in the table. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:does-not-exist </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-drag-elementdrag-element-and-drop-over-elementdrop-element\"></a><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></h2>\n<p>Clicks on <code>:elementDrag</code> and moves it onto <code>:elementDrop</code> while left mouse button is pressed, and then release it.</p>\n<p>Note: This step is not working on HTML5!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-forms\"><span class=\"arrow-prev\">← </span><span>Forms</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-files\"><span>Files</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-infinitely-scroll-to-the-elementname-element\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\"><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-the-elementname-element-to-disappear\"><code>I wait for the &quot;:elementName&quot; element to disappear</code></a></li><li><a href=\"#i-scroll-to-the-elementname-element\"><code>I scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-press-the-keyname-key\"><code>I press the &quot;:keyName&quot; key</code></a></li><li><a href=\"#i-click-the-elementname-element\"><code>I click the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\"><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#the-elementname-element-is-visible\"><code>the &quot;:elementName&quot;&quot; element is visible</code></a></li><li><a href=\"#the-elementname-element-is-not-visible\"><code>the &quot;:elementName&quot;&quot; element is not visible</code></a></li><li><a href=\"#the-elementname-element-is-disabled\"><code>the &quot;:elementName&quot; element is disabled</code></a></li><li><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\"><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></a></li><li><a href=\"#there-are-following-elements-in-table-elementname\"><code>there are following elements in table &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\"><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-are-elementname-dropdown-list-elements-with-following-options\"><code>there are &quot;:elementName&quot; dropdown list elements with following options:</code></a></li><li><a href=\"#there-is-element-elementname-with-value-matcher\"><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-element-elementname-containing-matcher-text\"><code>there is element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></a></li><li><a href=\"#there-is-element-elementname-matching-matcher-matcher\"><code>there is element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></a></li><li><a href=\"#there-is-element-elementname-with-regex-matcher\"><code>there is element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-with-value-matchername\"><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-containing-matcher-text\"><code>there is no element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></a></li><li><a href=\"#there-is-no-element-elementname-matching-matcher-matcher\"><code>there is no element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></a></li><li><a href=\"#there-is-no-element-elementname-with-regex-matcher\"><code>there is no element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></a></li><li><a href=\"#there-are-numberexpression-elementname-elements\"><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></a></li><li><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\"><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></a></li><li><a href=\"#the-element-elementname-should-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should have an item with values:</code></a></li><li><a href=\"#the-element-elementname-should-not-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should not have an item with values:</code></a></li><li><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\"><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-files/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Files · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with files:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Files · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with files:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Files</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-files\"></a><a href=\"#steps-used-to-interact-with-files\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with files:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-should-be-downloaded\"></a><a href=\"#the-file-filename-should-be-downloaded\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; should be downloaded</code></h2>\n<p>Checks if a file with name <code>:fileName</code> was downloaded.</p>\n<p>This step does not support matchers or regular expressions, so the name must be exact match. However you can use\nvariable store here.</p>\n<p>Let's assume there is a variable <code>myFile</code> with a value <code>super-file</code> in variable store.</p>\n<p>You can write <code>the file &quot;v:myFile.zip&quot; should be downloaded</code> to check if a file <code>super-file.zip</code> was downloaded.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-contains-table-data-stored-under-variablename-variable\"></a><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></h2>\n<p>This step allows you to compare an xls/xlsx file <code>:fileName</code> with an existing data stored under <code>:variableName</code> variable.</p>\n<p>The data under <code>:variableName</code> must be an array of objects representing each row of file.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-elements\"><span class=\"arrow-prev\">← </span><span>Elements</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-generators\"><span>Generators</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#the-file-filename-should-be-downloaded\"><code>the file &quot;:fileName&quot; should be downloaded</code></a></li><li><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\"><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-files.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Files · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with files:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Files · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with files:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Files</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-files\"></a><a href=\"#steps-used-to-interact-with-files\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with files:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-should-be-downloaded\"></a><a href=\"#the-file-filename-should-be-downloaded\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; should be downloaded</code></h2>\n<p>Checks if a file with name <code>:fileName</code> was downloaded.</p>\n<p>This step does not support matchers or regular expressions, so the name must be exact match. However you can use\nvariable store here.</p>\n<p>Let's assume there is a variable <code>myFile</code> with a value <code>super-file</code> in variable store.</p>\n<p>You can write <code>the file &quot;v:myFile.zip&quot; should be downloaded</code> to check if a file <code>super-file.zip</code> was downloaded.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-contains-table-data-stored-under-variablename-variable\"></a><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></h2>\n<p>This step allows you to compare an xls/xlsx file <code>:fileName</code> with an existing data stored under <code>:variableName</code> variable.</p>\n<p>The data under <code>:variableName</code> must be an array of objects representing each row of file.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-elements\"><span class=\"arrow-prev\">← </span><span>Elements</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-generators\"><span>Generators</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#the-file-filename-should-be-downloaded\"><code>the file &quot;:fileName&quot; should be downloaded</code></a></li><li><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\"><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-forms/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Forms · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to fill forms:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Forms · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to fill forms:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Forms</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-fill-forms\"></a><a href=\"#steps-used-to-fill-forms\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to fill forms:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-fill-the-formname-form-with\"></a><a href=\"#i-fill-the-formname-form-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I fill the &quot;:formName&quot; form with:</code></h2>\n<p>Allows to fill the form with the name <code>:formName</code> and values provided as an array of inputs and values. The element with name <code>:formName</code> must be defined inside the\n<code>currentPage</code> page object.</p>\n<p>Input and values should be provided as an array for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> value to be typed into field        </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> value to be typed into textarea     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> radio value to be selected          </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> checkbox label value to be selected </span>|\n</code></pre>\n<p>By default we support all basic HTML field types (text inputs, checkboxes, radios, selects, files and textareas)</p>\n<p>In order to use the default handlers the elements you use as input must follow pattern:</p>\n<p>For inputs:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill</p>\n<p>For textareas:</p>\n<p><code>this.element = $('textarea')</code> - element should point at textarea you want to fill</p>\n<p>For file input:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill and value should a filename of file from <code>data</code> directory</p>\n<p>For selects:</p>\n<p><code>this.element = $('select')</code> - element should point at select and value should be an value of expected option</p>\n<p>For radios:</p>\n<p><code>this.element = $$('radio[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all radio input of given name and value should be an value of radio you wish to select</p>\n<p>For checkboxes:</p>\n<p>Checkbox should have a html like:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label</span>&gt;</span>\n  My checkbox\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"checkbox\"</span> <span class=\"hljs-attr\">name</span>=<span class=\"hljs-string\">\"some-name\"</span>/&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">label</span>&gt;</span>\n</code></pre>\n<p><code>this.element = $$('checkbox[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all checkboxes of given name and value should be a text from label of checkbox you want to fill</p>\n<p>You can use all kind of transformers to as a values for fields.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-formname-form-is-filled-with\"></a><a href=\"#the-formname-form-is-filled-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:formName&quot; form is filled with:</code></h2>\n<p>The same as <code>I fill the &quot;:formName&quot; form with:</code> but allows to check if a form is filled with a given set of values.</p>\n<p>You can use all kind of transformers to as a expected values for fields.</p>\n<p>The only difference is for file fields. You cannot check uploaded files just like that, however we prepared a special type of handler\nthat allow to check for some information related to a specific file.</p>\n<p>Let's assume that after upload we display an information with a file name of a uploaded file.</p>\n<p>You can use a special handler that requires to set a element with a postfix <code>Uploaded</code>. This will check if a value of that element is the same as you expected.</p>\n<p>For example you can write a step like this:</p>\n<pre><code class=\"hljs css language-gherkin\">the <span class=\"hljs-string\">\"myform\"</span> form is filled with:\n  |<span class=\"hljs-string\"> myFileUploaded </span>|<span class=\"hljs-string\"> file.txt </span>|\n</code></pre>\n<p>Keep in mind that the element name must end with <code>Uploaded</code> for example:</p>\n<p><code>this.myFileUploaded = $('p.some-file')</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-error-messages-should-be-displayed\"></a><a href=\"#the-error-messages-should-be-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the error messages should be displayed:</code></h2>\n<p>Allows you to specify the error messages that should be displayed for a specific elements.</p>\n<p>This step requires an array of format:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> my error message </span>|\n</code></pre>\n<p>You can use dictionaries in this step as follows:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> d:dictionaryName:dictionaryKey </span>|\n</code></pre>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-navigation\"><span class=\"arrow-prev\">← </span><span>Navigation</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-elements\"><span>Elements</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-fill-the-formname-form-with\"><code>I fill the &quot;:formName&quot; form with:</code></a></li><li><a href=\"#the-formname-form-is-filled-with\"><code>the &quot;:formName&quot; form is filled with:</code></a></li><li><a href=\"#the-error-messages-should-be-displayed\"><code>the error messages should be displayed:</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-forms.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Forms · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to fill forms:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Forms · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to fill forms:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Forms</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-fill-forms\"></a><a href=\"#steps-used-to-fill-forms\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to fill forms:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-fill-the-formname-form-with\"></a><a href=\"#i-fill-the-formname-form-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I fill the &quot;:formName&quot; form with:</code></h2>\n<p>Allows to fill the form with the name <code>:formName</code> and values provided as an array of inputs and values. The element with name <code>:formName</code> must be defined inside the\n<code>currentPage</code> page object.</p>\n<p>Input and values should be provided as an array for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> value to be typed into field        </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> value to be typed into textarea     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> radio value to be selected          </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> checkbox label value to be selected </span>|\n</code></pre>\n<p>By default we support all basic HTML field types (text inputs, checkboxes, radios, selects, files and textareas)</p>\n<p>In order to use the default handlers the elements you use as input must follow pattern:</p>\n<p>For inputs:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill</p>\n<p>For textareas:</p>\n<p><code>this.element = $('textarea')</code> - element should point at textarea you want to fill</p>\n<p>For file input:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill and value should a filename of file from <code>data</code> directory</p>\n<p>For selects:</p>\n<p><code>this.element = $('select')</code> - element should point at select and value should be an value of expected option</p>\n<p>For radios:</p>\n<p><code>this.element = $$('radio[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all radio input of given name and value should be an value of radio you wish to select</p>\n<p>For checkboxes:</p>\n<p>Checkbox should have a html like:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label</span>&gt;</span>\n  My checkbox\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"checkbox\"</span> <span class=\"hljs-attr\">name</span>=<span class=\"hljs-string\">\"some-name\"</span>/&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">label</span>&gt;</span>\n</code></pre>\n<p><code>this.element = $$('checkbox[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all checkboxes of given name and value should be a text from label of checkbox you want to fill</p>\n<p>You can use all kind of transformers to as a values for fields.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-formname-form-is-filled-with\"></a><a href=\"#the-formname-form-is-filled-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:formName&quot; form is filled with:</code></h2>\n<p>The same as <code>I fill the &quot;:formName&quot; form with:</code> but allows to check if a form is filled with a given set of values.</p>\n<p>You can use all kind of transformers to as a expected values for fields.</p>\n<p>The only difference is for file fields. You cannot check uploaded files just like that, however we prepared a special type of handler\nthat allow to check for some information related to a specific file.</p>\n<p>Let's assume that after upload we display an information with a file name of a uploaded file.</p>\n<p>You can use a special handler that requires to set a element with a postfix <code>Uploaded</code>. This will check if a value of that element is the same as you expected.</p>\n<p>For example you can write a step like this:</p>\n<pre><code class=\"hljs css language-gherkin\">the <span class=\"hljs-string\">\"myform\"</span> form is filled with:\n  |<span class=\"hljs-string\"> myFileUploaded </span>|<span class=\"hljs-string\"> file.txt </span>|\n</code></pre>\n<p>Keep in mind that the element name must end with <code>Uploaded</code> for example:</p>\n<p><code>this.myFileUploaded = $('p.some-file')</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-error-messages-should-be-displayed\"></a><a href=\"#the-error-messages-should-be-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the error messages should be displayed:</code></h2>\n<p>Allows you to specify the error messages that should be displayed for a specific elements.</p>\n<p>This step requires an array of format:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> my error message </span>|\n</code></pre>\n<p>You can use dictionaries in this step as follows:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> d:dictionaryName:dictionaryKey </span>|\n</code></pre>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-navigation\"><span class=\"arrow-prev\">← </span><span>Navigation</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-elements\"><span>Elements</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-fill-the-formname-form-with\"><code>I fill the &quot;:formName&quot; form with:</code></a></li><li><a href=\"#the-formname-form-is-filled-with\"><code>the &quot;:formName&quot; form is filled with:</code></a></li><li><a href=\"#the-error-messages-should-be-displayed\"><code>the error messages should be displayed:</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-generators/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Generators · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to generate values:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Generators · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to generate values:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Generators</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-generate-values\"></a><a href=\"#steps-used-to-generate-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to generate values:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-generate-random-generatorparamparam-as-variablename\"></a><a href=\"#i-generate-random-generatorparamparam-as-variablename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></h2>\n<p>Allows to generate a random value using the generator specified by <code>:generator:param:param</code>.</p>\n<p>The generator must be defined inside the any of the <code>generators</code> directories specified in <code>kakunin.conf.js</code> file <code>default: generators</code>.</p>\n<p>If the generator exists, then the value will be saved under the <code>:variableName</code> and can be accessed by:</p>\n<ul>\n<li><p>steps using variable store</p></li>\n<li><p>by calling <code>variableStore.getVariableValue(:variableName)</code></p></li>\n<li><p>by using variable store transformer on supported steps <code>v:variableName</code></p></li>\n</ul>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-files\"><span class=\"arrow-prev\">← </span><span>Files</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-debug\"><span>Debug</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-generate-random-generatorparamparam-as-variablename\"><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-generators.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Generators · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to generate values:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Generators · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to generate values:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Generators</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-generate-values\"></a><a href=\"#steps-used-to-generate-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to generate values:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-generate-random-generatorparamparam-as-variablename\"></a><a href=\"#i-generate-random-generatorparamparam-as-variablename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></h2>\n<p>Allows to generate a random value using the generator specified by <code>:generator:param:param</code>.</p>\n<p>The generator must be defined inside the any of the <code>generators</code> directories specified in <code>kakunin.conf.js</code> file <code>default: generators</code>.</p>\n<p>If the generator exists, then the value will be saved under the <code>:variableName</code> and can be accessed by:</p>\n<ul>\n<li><p>steps using variable store</p></li>\n<li><p>by calling <code>variableStore.getVariableValue(:variableName)</code></p></li>\n<li><p>by using variable store transformer on supported steps <code>v:variableName</code></p></li>\n</ul>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-files\"><span class=\"arrow-prev\">← </span><span>Files</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-debug\"><span>Debug</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-generate-random-generatorparamparam-as-variablename\"><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-navigation/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Navigation · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used for navigation on page:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Navigation · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used for navigation on page:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Navigation</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-for-navigation-on-page\"></a><a href=\"#steps-used-for-navigation-on-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used for navigation on page:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page\"></a><a href=\"#i-visit-the-pagefilename-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page</code></h2>\n<p>Visits the url of the page object with <code>:pageFileName</code> name.</p>\n<p>In order to make it work we create a page object file with a name of <code>:pageFileName</code>.</p>\n<p>For example in case of: <code>I visit the &quot;myPage&quot; page</code> there should be a file <code>myPage.js</code> inside the <code>pages</code> directory.</p>\n<p>If we have a page object with a name <code>somePageObject.js</code> defined inside <code>pages</code> directory then:</p>\n<p><code>Given I visit the &quot;somePageObject&quot; page</code></p>\n<p>will set <code>this.currentPage</code> variable to <code>somePageObject</code> page and we should end up on <code>somePageObject</code> url.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page-with-parameters\"></a><a href=\"#i-visit-the-pagefilename-page-with-parameters\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></h2>\n<p>The same as <code>I visit the &quot;:pageFileName&quot; page</code> except allows to pass url parameters.</p>\n<p>If url of <code>myPage</code> is defined as <code>this.url = /orders/:orderId/products/:productId</code> then we can use this step to visit this page by:</p>\n<pre><code class=\"hljs css language-gherkin\">I visit the <span class=\"hljs-string\">\"myPage\"</span> page with parameters:\n    |<span class=\"hljs-string\"> orderId   </span>|<span class=\"hljs-string\"> 1 </span>|\n    |<span class=\"hljs-string\"> productId </span>|<span class=\"hljs-string\"> 2 </span>|\n</code></pre>\n<p>this will result in visiting the <code>/orders/1/product/2</code> page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-pagefilename-page-is-displayed\"></a><a href=\"#the-pagefilename-page-is-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:pageFileName&quot; page is displayed</code></h2>\n<p>Checks if current browser url matches url of <code>pageFileName</code> page object.</p>\n<p>If the url matches expected pattern then\n<code>this.currentPage</code> variable is set to <code>pageFileName</code> page object.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/testing-rest-api\"><span class=\"arrow-prev\">← </span><span>REST API examples</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-forms\"><span>Forms</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-visit-the-pagefilename-page\"><code>I visit the &quot;:pageFileName&quot; page</code></a></li><li><a href=\"#i-visit-the-pagefilename-page-with-parameters\"><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></a></li><li><a href=\"#the-pagefilename-page-is-displayed\"><code>the &quot;:pageFileName&quot; page is displayed</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-navigation.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Navigation · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used for navigation on page:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Navigation · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used for navigation on page:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Navigation</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-for-navigation-on-page\"></a><a href=\"#steps-used-for-navigation-on-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used for navigation on page:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page\"></a><a href=\"#i-visit-the-pagefilename-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page</code></h2>\n<p>Visits the url of the page object with <code>:pageFileName</code> name.</p>\n<p>In order to make it work we create a page object file with a name of <code>:pageFileName</code>.</p>\n<p>For example in case of: <code>I visit the &quot;myPage&quot; page</code> there should be a file <code>myPage.js</code> inside the <code>pages</code> directory.</p>\n<p>If we have a page object with a name <code>somePageObject.js</code> defined inside <code>pages</code> directory then:</p>\n<p><code>Given I visit the &quot;somePageObject&quot; page</code></p>\n<p>will set <code>this.currentPage</code> variable to <code>somePageObject</code> page and we should end up on <code>somePageObject</code> url.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page-with-parameters\"></a><a href=\"#i-visit-the-pagefilename-page-with-parameters\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></h2>\n<p>The same as <code>I visit the &quot;:pageFileName&quot; page</code> except allows to pass url parameters.</p>\n<p>If url of <code>myPage</code> is defined as <code>this.url = /orders/:orderId/products/:productId</code> then we can use this step to visit this page by:</p>\n<pre><code class=\"hljs css language-gherkin\">I visit the <span class=\"hljs-string\">\"myPage\"</span> page with parameters:\n    |<span class=\"hljs-string\"> orderId   </span>|<span class=\"hljs-string\"> 1 </span>|\n    |<span class=\"hljs-string\"> productId </span>|<span class=\"hljs-string\"> 2 </span>|\n</code></pre>\n<p>this will result in visiting the <code>/orders/1/product/2</code> page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-pagefilename-page-is-displayed\"></a><a href=\"#the-pagefilename-page-is-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:pageFileName&quot; page is displayed</code></h2>\n<p>Checks if current browser url matches url of <code>pageFileName</code> page object.</p>\n<p>If the url matches expected pattern then\n<code>this.currentPage</code> variable is set to <code>pageFileName</code> page object.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/testing-rest-api\"><span class=\"arrow-prev\">← </span><span>REST API examples</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-forms\"><span>Forms</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-visit-the-pagefilename-page\"><code>I visit the &quot;:pageFileName&quot; page</code></a></li><li><a href=\"#i-visit-the-pagefilename-page-with-parameters\"><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></a></li><li><a href=\"#the-pagefilename-page-is-displayed\"><code>the &quot;:pageFileName&quot; page is displayed</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-rest/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Rest api · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used for testing REST api:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Rest api · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used for testing REST api:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Rest api</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-for-testing-rest-api\"></a><a href=\"#steps-used-for-testing-rest-api\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used for testing REST api:</h1>\n<p>In order to configure url for api, please change <code>apiUrl</code> field in <code>functional-tests/kakunin.conf.js</code>. This will set url of application api.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-send-methodname-request-on-endpoint-endpoint\"></a><a href=\"#i-send-methodname-request-on-endpoint-endpoint\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I send &quot;:methodName&quot; request on &quot;:endpoint&quot; endpoint</code></h2>\n<p>Sends to the given request method to given website endpoint.</p>\n<p>For example, in case of GET request for /posts endpoint it should look like:</p>\n<pre><code class=\"hljs css language-gherkin\">I send <span class=\"hljs-string\">\"GET\"</span> request on <span class=\"hljs-string\">\"posts\"</span> endpoint\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-send-methodname-request-on-endpoint-endpoint-with-json-body\"></a><a href=\"#i-send-methodname-request-on-endpoint-endpoint-with-json-body\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>^I send &quot;:methodName&quot; request on &quot;:endpoint&quot; endpoint with JSON body:</code></h2>\n<p>Sends request method to website endpoint requiring JSON body.</p>\n<pre><code class=\"hljs css language-gherkin\">I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"posts\"</span> endpoint with JSON body:\n    <span class=\"hljs-string\">\"\"\"\n    {\n        \"title\": \"user\",\n        \"body\": \"test\"\n    }\n    \"\"\"</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-send-methodname-request-on-endpoint-endpoint-using-form-data\"></a><a href=\"#i-send-methodname-request-on-endpoint-endpoint-using-form-data\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>^I send &quot;methodName&quot; request on &quot;:endpoint&quot; endpoint using form data:</code></h2>\n<p>Sends request method to website endpoint using form data.</p>\n<pre><code class=\"hljs css language-gherkin\">I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"posts\"</span> endpoint using form data:\n    |<span class=\"hljs-string\"> title </span>|<span class=\"hljs-string\"> user </span>|\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-response-code-should-be-statuscode\"></a><a href=\"#the-response-code-should-be-statuscode\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the response code should be &quot;:statusCode&quot;</code></h2>\n<p>Verifies if the server response code has match to given one.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-response-should-exact-match-to-body\"></a><a href=\"#the-response-should-exact-match-to-body\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the response should exact match to body:</code></h2>\n<p>Verifies if the server response body has exact match to given one.</p>\n<pre><code class=\"hljs css language-gherkin\">the response should exact match to body:\n    <span class=\"hljs-string\">\"\"\"\n    {\n        \"userId\": 1,\n        \"id\": 1,\n        \"title\": \"user\",\n        \"body\": \"test\"\n    }\n    \"\"\"</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-response-should-match-json-schema\"></a><a href=\"#the-response-should-match-json-schema\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the response should match JSON schema:</code></h2>\n<p>Verifies if the server response body has exact match to given JSON schema.</p>\n<pre><code class=\"hljs css language-gherkin\">the response should exact match JSON schema:\n    <span class=\"hljs-string\">\"\"\"\n    {\n        \"title\": \"Test schema\",\n        \"type\": \"object\",\n        \"properties\": {\n            \"id\": {\n                \"type\": \"integer\"\n            }\n        },\n        \"required\": [\"id\"]\n    }\n    \"\"\"</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-set-request-headers\"></a><a href=\"#i-set-request-headers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I set request headers:</code></h2>\n<p>Sets the request headers to given one till creating new request.</p>\n<pre><code class=\"hljs css language-gherkin\">I set request headers:\n    |<span class=\"hljs-string\"> Content-type </span>|<span class=\"hljs-string\"> application/json </span>|\n    |<span class=\"hljs-string\"> accept       </span>|<span class=\"hljs-string\"> */*              </span>|\n</code></pre>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-debug\"><span class=\"arrow-prev\">← </span><span>Debug</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-send-methodname-request-on-endpoint-endpoint\"><code>I send &quot;:methodName&quot; request on &quot;:endpoint&quot; endpoint</code></a></li><li><a href=\"#i-send-methodname-request-on-endpoint-endpoint-with-json-body\"><code>^I send &quot;:methodName&quot; request on &quot;:endpoint&quot; endpoint with JSON body:</code></a></li><li><a href=\"#i-send-methodname-request-on-endpoint-endpoint-using-form-data\"><code>^I send &quot;methodName&quot; request on &quot;:endpoint&quot; endpoint using form data:</code></a></li><li><a href=\"#the-response-code-should-be-statuscode\"><code>the response code should be &quot;:statusCode&quot;</code></a></li><li><a href=\"#the-response-should-exact-match-to-body\"><code>the response should exact match to body:</code></a></li><li><a href=\"#the-response-should-match-json-schema\"><code>the response should match JSON schema:</code></a></li><li><a href=\"#i-set-request-headers\"><code>I set request headers:</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/steps-rest.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Rest api · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used for testing REST api:\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Rest api · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used for testing REST api:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Rest api</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-for-testing-rest-api\"></a><a href=\"#steps-used-for-testing-rest-api\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used for testing REST api:</h1>\n<p>In order to configure url for api, please change <code>apiUrl</code> field in <code>functional-tests/kakunin.conf.js</code>. This will set url of application api.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-send-methodname-request-on-endpoint-endpoint\"></a><a href=\"#i-send-methodname-request-on-endpoint-endpoint\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I send &quot;:methodName&quot; request on &quot;:endpoint&quot; endpoint</code></h2>\n<p>Sends to the given request method to given website endpoint.</p>\n<p>For example, in case of GET request for /posts endpoint it should look like:</p>\n<pre><code class=\"hljs css language-gherkin\">I send <span class=\"hljs-string\">\"GET\"</span> request on <span class=\"hljs-string\">\"posts\"</span> endpoint\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-send-methodname-request-on-endpoint-endpoint-with-json-body\"></a><a href=\"#i-send-methodname-request-on-endpoint-endpoint-with-json-body\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>^I send &quot;:methodName&quot; request on &quot;:endpoint&quot; endpoint with JSON body:</code></h2>\n<p>Sends request method to website endpoint requiring JSON body.</p>\n<pre><code class=\"hljs css language-gherkin\">I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"posts\"</span> endpoint with JSON body:\n    <span class=\"hljs-string\">\"\"\"\n    {\n        \"title\": \"user\",\n        \"body\": \"test\"\n    }\n    \"\"\"</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-send-methodname-request-on-endpoint-endpoint-using-form-data\"></a><a href=\"#i-send-methodname-request-on-endpoint-endpoint-using-form-data\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>^I send &quot;methodName&quot; request on &quot;:endpoint&quot; endpoint using form data:</code></h2>\n<p>Sends request method to website endpoint using form data.</p>\n<pre><code class=\"hljs css language-gherkin\">I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"posts\"</span> endpoint using form data:\n    |<span class=\"hljs-string\"> title </span>|<span class=\"hljs-string\"> user </span>|\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-response-code-should-be-statuscode\"></a><a href=\"#the-response-code-should-be-statuscode\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the response code should be &quot;:statusCode&quot;</code></h2>\n<p>Verifies if the server response code has match to given one.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-response-should-exact-match-to-body\"></a><a href=\"#the-response-should-exact-match-to-body\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the response should exact match to body:</code></h2>\n<p>Verifies if the server response body has exact match to given one.</p>\n<pre><code class=\"hljs css language-gherkin\">the response should exact match to body:\n    <span class=\"hljs-string\">\"\"\"\n    {\n        \"userId\": 1,\n        \"id\": 1,\n        \"title\": \"user\",\n        \"body\": \"test\"\n    }\n    \"\"\"</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-response-should-match-json-schema\"></a><a href=\"#the-response-should-match-json-schema\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the response should match JSON schema:</code></h2>\n<p>Verifies if the server response body has exact match to given JSON schema.</p>\n<pre><code class=\"hljs css language-gherkin\">the response should exact match JSON schema:\n    <span class=\"hljs-string\">\"\"\"\n    {\n        \"title\": \"Test schema\",\n        \"type\": \"object\",\n        \"properties\": {\n            \"id\": {\n                \"type\": \"integer\"\n            }\n        },\n        \"required\": [\"id\"]\n    }\n    \"\"\"</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-set-request-headers\"></a><a href=\"#i-set-request-headers\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I set request headers:</code></h2>\n<p>Sets the request headers to given one till creating new request.</p>\n<pre><code class=\"hljs css language-gherkin\">I set request headers:\n    |<span class=\"hljs-string\"> Content-type </span>|<span class=\"hljs-string\"> application/json </span>|\n    |<span class=\"hljs-string\"> accept       </span>|<span class=\"hljs-string\"> */*              </span>|\n</code></pre>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/steps-debug\"><span class=\"arrow-prev\">← </span><span>Debug</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-send-methodname-request-on-endpoint-endpoint\"><code>I send &quot;:methodName&quot; request on &quot;:endpoint&quot; endpoint</code></a></li><li><a href=\"#i-send-methodname-request-on-endpoint-endpoint-with-json-body\"><code>^I send &quot;:methodName&quot; request on &quot;:endpoint&quot; endpoint with JSON body:</code></a></li><li><a href=\"#i-send-methodname-request-on-endpoint-endpoint-using-form-data\"><code>^I send &quot;methodName&quot; request on &quot;:endpoint&quot; endpoint using form data:</code></a></li><li><a href=\"#the-response-code-should-be-statuscode\"><code>the response code should be &quot;:statusCode&quot;</code></a></li><li><a href=\"#the-response-should-exact-match-to-body\"><code>the response should exact match to body:</code></a></li><li><a href=\"#the-response-should-match-json-schema\"><code>the response should match JSON schema:</code></a></li><li><a href=\"#i-set-request-headers\"><code>I set request headers:</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/testing-rest-api/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>REST API examples · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Testing REST API of your application\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"REST API examples · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Testing REST API of your application\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">REST API examples</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"testing-rest-api-of-your-application\"></a><a href=\"#testing-rest-api-of-your-application\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Testing REST API of your application</h1>\n<p>In this section examples of using steps provided for testing, REST API will be provided.\nAll examples can be checked on site <a href=\"https://reqres.in/\">https://reqres.in/</a> which is simple REST API service</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"available-methods\"></a><a href=\"#available-methods\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Available methods</h1>\n<p>At this moment Kakunin supports methods for REST API:</p>\n<ul>\n<li>GET</li>\n<li>POST</li>\n<li>DELETE</li>\n<li>PATCH</li>\n</ul>\n<p>Also, You can set the headers for the request.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"making-get-request\"></a><a href=\"#making-get-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Making GET request</h1>\n<p>In order to create get request and verify if the response is ok you need to create scenario step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"GET\"</span> request on <span class=\"hljs-string\">\"/api/users/2\"</span> endpoint\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"200\"</span>\n</code></pre>\n<p>This scenario will create a get request to the application and verify if the response was 200.\nThe response is stored till creating another request. So if We want to test the response body of a server we can create a scenario like:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"GET\"</span> request on <span class=\"hljs-string\">\"/api/users/2\"</span> endpoint\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"200\"</span>\n<span class=\"hljs-keyword\">And</span> the response should exact match to body:\n    <span class=\"hljs-string\">\"\"\"\n    {\n        \"data\": {\n            \"id\": 2,\n            \"first_name\": \"Janet\",\n            \"last_name\": \"Weaver\",\n            \"avatar\": \"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg\"\n        }\n    }\n    \"\"\"</span>\n</code></pre>\n<p>Based on this We can also check if the response matches schema that we have provided by using step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Then</span> the response should exact match JSON schema:\n</code></pre>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"making-post-request\"></a><a href=\"#making-post-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Making POST request</h1>\n<p>In order to create post request and attach the JSON body to it You need to create a scenario:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"/api/users\"</span> endpoint with body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"leader\"\n  }\n  \"\"\"</span>\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"201\"</span>\n</code></pre>\n<p>or you can create post request and attach the form data to it:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"/api/users\"</span> endpoint using form data:\n  |<span class=\"hljs-string\"> name </span>|<span class=\"hljs-string\"> morpheus </span>|\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"201\"</span>\n</code></pre>\n<p>This scenario will create a post request to the application and verify if response was 201 (created).\nThe response is stored till creating another request. So if We want to test the response body of a server we can create scenarios\nlike before:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"/api/users\"</span> endpoint with body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"leader\"\n  }\n  \"\"\"</span>\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"201\"</span>\n<span class=\"hljs-keyword\">And</span> the response should match JSON schema:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"title\": \"Post schema\",\n      \"type\": \"object\",\n      \"properties\": {\n          \"name\": {\n              \"type\": \"string\"\n          },\n          \"job\": {\n              \"type\": \"string\"\n          }\n      },\n      \"required\": [\"name\", \"job\"]\n  }\n  \"\"\"</span>\n</code></pre>\n<p>Scenario like that will verify if the post request was executed and response schema matches given one.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"making-delete-request\"></a><a href=\"#making-delete-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Making DELETE request</h1>\n<p>Delete request works similarly to get request. Example of delete scenario:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"DELETE\"</span> request on <span class=\"hljs-string\">\"/api/users/2\"</span> endpoint\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"204\"</span>\n</code></pre>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"making-patch-request\"></a><a href=\"#making-patch-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Making PATCH request</h1>\n<p>Patch request works similarly to post request. Example of patch scenario:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"PATCH\"</span> request on <span class=\"hljs-string\">\"/api/users/2\"</span> endpoint with JSON body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"zion resident\"\n  }\n  \"\"\"</span>\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"200\"</span>\n<span class=\"hljs-keyword\">And</span> the response should exact match to body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"zion resident\",\n      \"updatedAt\": \"2019-02-12T18:25:06.001Z\"\n  }\n  \"\"\"</span>\n</code></pre>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"setting-headers-for-request\"></a><a href=\"#setting-headers-for-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting headers for request</h1>\n<p>Sometimes We want to set the headers for next request. In order to achieve this, We can create scenario like:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I set request headers:\n  |<span class=\"hljs-string\"> User-Agent </span>|<span class=\"hljs-string\"> Mozilla </span>|\n<span class=\"hljs-keyword\">When</span> I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"postTestEndpoint\"</span> endpoint with JSON body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"title\": \"adam\",\n      \"body\": \"test\"\n  }\n  \"\"\"</span>\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"403\"</span>\n</code></pre>\n<p>This scenario will set &quot;User-Agent&quot; header of next request to &quot;Mozilla&quot;.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/docker\"><span class=\"arrow-prev\">← </span><span>Docker</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-navigation\"><span>Navigation</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/testing-rest-api.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>REST API examples · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Testing REST API of your application\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"REST API examples · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Testing REST API of your application\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">REST API examples</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"testing-rest-api-of-your-application\"></a><a href=\"#testing-rest-api-of-your-application\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Testing REST API of your application</h1>\n<p>In this section examples of using steps provided for testing, REST API will be provided.\nAll examples can be checked on site <a href=\"https://reqres.in/\">https://reqres.in/</a> which is simple REST API service</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"available-methods\"></a><a href=\"#available-methods\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Available methods</h1>\n<p>At this moment Kakunin supports methods for REST API:</p>\n<ul>\n<li>GET</li>\n<li>POST</li>\n<li>DELETE</li>\n<li>PATCH</li>\n</ul>\n<p>Also, You can set the headers for the request.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"making-get-request\"></a><a href=\"#making-get-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Making GET request</h1>\n<p>In order to create get request and verify if the response is ok you need to create scenario step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"GET\"</span> request on <span class=\"hljs-string\">\"/api/users/2\"</span> endpoint\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"200\"</span>\n</code></pre>\n<p>This scenario will create a get request to the application and verify if the response was 200.\nThe response is stored till creating another request. So if We want to test the response body of a server we can create a scenario like:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"GET\"</span> request on <span class=\"hljs-string\">\"/api/users/2\"</span> endpoint\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"200\"</span>\n<span class=\"hljs-keyword\">And</span> the response should exact match to body:\n    <span class=\"hljs-string\">\"\"\"\n    {\n        \"data\": {\n            \"id\": 2,\n            \"first_name\": \"Janet\",\n            \"last_name\": \"Weaver\",\n            \"avatar\": \"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg\"\n        }\n    }\n    \"\"\"</span>\n</code></pre>\n<p>Based on this We can also check if the response matches schema that we have provided by using step:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Then</span> the response should exact match JSON schema:\n</code></pre>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"making-post-request\"></a><a href=\"#making-post-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Making POST request</h1>\n<p>In order to create post request and attach the JSON body to it You need to create a scenario:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"/api/users\"</span> endpoint with body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"leader\"\n  }\n  \"\"\"</span>\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"201\"</span>\n</code></pre>\n<p>or you can create post request and attach the form data to it:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"/api/users\"</span> endpoint using form data:\n  |<span class=\"hljs-string\"> name </span>|<span class=\"hljs-string\"> morpheus </span>|\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"201\"</span>\n</code></pre>\n<p>This scenario will create a post request to the application and verify if response was 201 (created).\nThe response is stored till creating another request. So if We want to test the response body of a server we can create scenarios\nlike before:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"/api/users\"</span> endpoint with body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"leader\"\n  }\n  \"\"\"</span>\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"201\"</span>\n<span class=\"hljs-keyword\">And</span> the response should match JSON schema:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"title\": \"Post schema\",\n      \"type\": \"object\",\n      \"properties\": {\n          \"name\": {\n              \"type\": \"string\"\n          },\n          \"job\": {\n              \"type\": \"string\"\n          }\n      },\n      \"required\": [\"name\", \"job\"]\n  }\n  \"\"\"</span>\n</code></pre>\n<p>Scenario like that will verify if the post request was executed and response schema matches given one.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"making-delete-request\"></a><a href=\"#making-delete-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Making DELETE request</h1>\n<p>Delete request works similarly to get request. Example of delete scenario:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"DELETE\"</span> request on <span class=\"hljs-string\">\"/api/users/2\"</span> endpoint\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"204\"</span>\n</code></pre>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"making-patch-request\"></a><a href=\"#making-patch-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Making PATCH request</h1>\n<p>Patch request works similarly to post request. Example of patch scenario:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I send <span class=\"hljs-string\">\"PATCH\"</span> request on <span class=\"hljs-string\">\"/api/users/2\"</span> endpoint with JSON body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"zion resident\"\n  }\n  \"\"\"</span>\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"200\"</span>\n<span class=\"hljs-keyword\">And</span> the response should exact match to body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"name\": \"morpheus\",\n      \"job\": \"zion resident\",\n      \"updatedAt\": \"2019-02-12T18:25:06.001Z\"\n  }\n  \"\"\"</span>\n</code></pre>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"setting-headers-for-request\"></a><a href=\"#setting-headers-for-request\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting headers for request</h1>\n<p>Sometimes We want to set the headers for next request. In order to achieve this, We can create scenario like:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Given</span> I set request headers:\n  |<span class=\"hljs-string\"> User-Agent </span>|<span class=\"hljs-string\"> Mozilla </span>|\n<span class=\"hljs-keyword\">When</span> I send <span class=\"hljs-string\">\"POST\"</span> request on <span class=\"hljs-string\">\"postTestEndpoint\"</span> endpoint with JSON body:\n  <span class=\"hljs-string\">\"\"\"\n  {\n      \"title\": \"adam\",\n      \"body\": \"test\"\n  }\n  \"\"\"</span>\n<span class=\"hljs-keyword\">Then</span> the response code should be <span class=\"hljs-string\">\"403\"</span>\n</code></pre>\n<p>This scenario will set &quot;User-Agent&quot; header of next request to &quot;Mozilla&quot;.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/docker\"><span class=\"arrow-prev\">← </span><span>Docker</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/steps-navigation\"><span>Navigation</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/transformers/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Transformers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Transformers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Transformers</h1></header><article><div><span><p>Transformers allow you to transform values passed to form steps.</p>\n<p>For example a select requires to pass a value <code>/options/1b30f17e-e445-4d28-a30c-dedad95829ab</code>. This one is quite unreadable, but with the help of transformers you are\nable to write it like this: <code>d:options:someOptionName</code>.</p>\n<p>In real-life example it will look similar to:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> d:someDictionary:someKey            </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> g:someGenerator                     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> v:someVariableName                  </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> standard value                      </span>|\n</code></pre>\n<p>There are 3 types of built-in transformers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h2>\n<p>Dictionaries allows you to transform a value A to value B using a simple key-&gt;value transformation.</p>\n<p>You can run a dictionary transformer by providing dictionary prefix <code>d:</code>, specifying the dictionary name and key that should be used as a value provider. For example:</p>\n<p><code>d:myDictionaryName:myDictionaryKey</code></p>\n<p>this example assumes that there is a dictionary that supports name <code>myDictionaryName</code> and it has <code>myDictionarKey</code> key.</p>\n<p>You can read about dictionaries in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h2>\n<p>Generators allows you to generate a value by using a specified generator.</p>\n<p>This can be done by: <code>g:generatorName</code>.</p>\n<p>If a generator supports parameters then you can specify them by:</p>\n<p><code>g:generatorName:param1:param2:...:paramN</code></p>\n<p>You can read more about generators in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h2>\n<p>Variable store allows you to fill the form with a value that was saved in previous steps of current running scenario.</p>\n<p>This can be done by:</p>\n<p><code>v:variableName</code></p>\n<p>You can read more about variable store in <code>Extending Kakunin</code> section</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/matchers\"><span class=\"arrow-prev\">← </span><span>Matchers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/extending\"><span>Extending Kakunin</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#variable-store\">Variable store</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/next/transformers.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Transformers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta name=\"docsearch:version\" content=\"next\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Transformers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>next</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/matchers\">Matchers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/next/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/extending\">Extending Kakunin</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/hooks\">Hooks</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/browserstack\">Browserstack integration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/headless\">Headless</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/docker\">Docker</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/testing-rest-api\">REST API examples</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-debug\">Debug</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/next/steps-rest\">Rest api</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Transformers</h1></header><article><div><span><p>Transformers allow you to transform values passed to form steps.</p>\n<p>For example a select requires to pass a value <code>/options/1b30f17e-e445-4d28-a30c-dedad95829ab</code>. This one is quite unreadable, but with the help of transformers you are\nable to write it like this: <code>d:options:someOptionName</code>.</p>\n<p>In real-life example it will look similar to:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> d:someDictionary:someKey            </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> g:someGenerator                     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> v:someVariableName                  </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> standard value                      </span>|\n</code></pre>\n<p>There are 3 types of built-in transformers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h2>\n<p>Dictionaries allows you to transform a value A to value B using a simple key-&gt;value transformation.</p>\n<p>You can run a dictionary transformer by providing dictionary prefix <code>d:</code>, specifying the dictionary name and key that should be used as a value provider. For example:</p>\n<p><code>d:myDictionaryName:myDictionaryKey</code></p>\n<p>this example assumes that there is a dictionary that supports name <code>myDictionaryName</code> and it has <code>myDictionarKey</code> key.</p>\n<p>You can read about dictionaries in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h2>\n<p>Generators allows you to generate a value by using a specified generator.</p>\n<p>This can be done by: <code>g:generatorName</code>.</p>\n<p>If a generator supports parameters then you can specify them by:</p>\n<p><code>g:generatorName:param1:param2:...:paramN</code></p>\n<p>You can read more about generators in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h2>\n<p>Variable store allows you to fill the form with a value that was saved in previous steps of current running scenario.</p>\n<p>This can be done by:</p>\n<p><code>v:variableName</code></p>\n<p>You can read more about variable store in <code>Extending Kakunin</code> section</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/next/matchers\"><span class=\"arrow-prev\">← </span><span>Matchers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/next/extending\"><span>Extending Kakunin</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#variable-store\">Variable store</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/parallel-testing/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Parallel testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"There is a possibility to run tests in parallel.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Parallel testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"There is a possibility to run tests in parallel.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Parallel testing</h1></header><article><div><span><p>There is a possibility to run tests in parallel.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-execute\"></a><a href=\"#how-to-execute\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to execute</h2>\n<p>Use a command <code>npm run kakunin -- --parallel &lt;number of instances&gt;</code> where <code>number of instances</code> is a number.</p>\n<p>Example:</p>\n<ul>\n<li><code>npm run kakunin -- --chrome --parallel 2</code></li>\n</ul>\n<p><span style=\"color:red\">Keep in mind that the merged report is available in the <code>reports/report/index.html</code> file. text</span></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"specify-pattern-per-each-instance\"></a><a href=\"#specify-pattern-per-each-instance\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Specify pattern per each instance</h2>\n<ul>\n<li><code>npm run kakunin -- --parallel &lt;number of instances&gt; --pattern &lt;regex to much feature&gt; --pattern &lt;regex to much feature&gt;</code></li>\n</ul>\n<p>Keep in mind that:</p>\n<ul>\n<li>the number given in <code>parallel</code> must be equal to passed <code>patterns</code></li>\n<li><code>&lt;number of instances&gt;</code> is a number of instances of the specified browser</li>\n<li><code>&lt;regex&gt;</code> is a pattern that is used to specify the list of specs that will be executed in each of the instances</li>\n</ul>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h2>\n<ol>\n<li>Running more than one instance in <code>Firefox</code> is not possible now (fix in-progress).</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/cross-browser\"><span class=\"arrow-prev\">← </span><span>Cross-browser testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/performance-testing\"><span>Performance testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#how-to-execute\">How to execute</a></li><li><a href=\"#specify-pattern-per-each-instance\">Specify pattern per each instance</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/parallel-testing.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Parallel testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"There is a possibility to run tests in parallel.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Parallel testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"There is a possibility to run tests in parallel.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Parallel testing</h1></header><article><div><span><p>There is a possibility to run tests in parallel.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"how-to-execute\"></a><a href=\"#how-to-execute\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to execute</h2>\n<p>Use a command <code>npm run kakunin -- --parallel &lt;number of instances&gt;</code> where <code>number of instances</code> is a number.</p>\n<p>Example:</p>\n<ul>\n<li><code>npm run kakunin -- --chrome --parallel 2</code></li>\n</ul>\n<p><span style=\"color:red\">Keep in mind that the merged report is available in the <code>reports/report/index.html</code> file. text</span></p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"specify-pattern-per-each-instance\"></a><a href=\"#specify-pattern-per-each-instance\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Specify pattern per each instance</h2>\n<ul>\n<li><code>npm run kakunin -- --parallel &lt;number of instances&gt; --pattern &lt;regex to much feature&gt; --pattern &lt;regex to much feature&gt;</code></li>\n</ul>\n<p>Keep in mind that:</p>\n<ul>\n<li>the number given in <code>parallel</code> must be equal to passed <code>patterns</code></li>\n<li><code>&lt;number of instances&gt;</code> is a number of instances of the specified browser</li>\n<li><code>&lt;regex&gt;</code> is a pattern that is used to specify the list of specs that will be executed in each of the instances</li>\n</ul>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"troubleshooting\"></a><a href=\"#troubleshooting\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Troubleshooting</h2>\n<ol>\n<li>Running more than one instance in <code>Firefox</code> is not possible now (fix in-progress).</li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/cross-browser\"><span class=\"arrow-prev\">← </span><span>Cross-browser testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/performance-testing\"><span>Performance testing</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#how-to-execute\">How to execute</a></li><li><a href=\"#specify-pattern-per-each-instance\">Specify pattern per each instance</a></li><li><a href=\"#troubleshooting\">Troubleshooting</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/performance-testing/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Performance testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Performance testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Performance testing</h1></header><article><div><span><p>Performance testing is possible thanks to <code>browsermob-proxy</code>.</p>\n<p>It saves all data from network tab (Google Chrome console) which is generated during the test.</p>\n<p>There is a possibility to compare <code>TTFB</code> value with a maximum given one.</p>\n<p><code>TTFB</code> (Time to first byte) measures the duration from the client making an HTTP request to the first byte of a response being received by the client's browser.</p>\n<p>More details can be found in documentation - <code>Built-in steps</code> section.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"what-needs-to-be-done\"></a><a href=\"#what-needs-to-be-done\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What needs to be done?</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"get-started\"></a><a href=\"#get-started\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get started</h2>\n<ol>\n<li><p>Download <code>browsermob-proxy</code> from <code>https://github.com/lightbody/browsermob-proxy</code></p></li>\n<li><p>Navigate in terminal to the catalog</p></li>\n<li><p>Use following command to start the REST API</p></li>\n</ol>\n<pre><code class=\"hljs\">./browsermob-proxy -port <span class=\"hljs-number\">8887</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ol>\n<li>Add <code>browsermob-proxy</code> configuration to <code>kakunin.conf.js</code></li>\n</ol>\n<p>You can use one of the following methods to configure browsermob-proxy:</p>\n<ul>\n<li><p><code>npm run kakunin init -- --advanced</code> and go through the process</p></li>\n<li><p>or add it manually to the config file:</p></li>\n</ul>\n<pre><code class=\"hljs css language-javascript\">    <span class=\"hljs-string\">\"browserMob\"</span>: {\n      <span class=\"hljs-string\">\"serverPort\"</span>: <span class=\"hljs-number\">8887</span>,\n      <span class=\"hljs-string\">\"port\"</span>: <span class=\"hljs-number\">8888</span>,\n      <span class=\"hljs-string\">\"host\"</span>: <span class=\"hljs-string\">\"localhost\"</span>\n    }\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h2>\n<ol>\n<li><p><code>performance steps</code> must be used in the scenario where you are testing performance</p></li>\n<li><p>Scenario must have a tag <code>@performance</code></p></li>\n<li><p>Run tests with special parameter:</p></li>\n</ol>\n<pre><code class=\"hljs\">npm <span class=\"hljs-built_in\">run</span> kakunin <span class=\"hljs-comment\">-- --performance</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"results\"></a><a href=\"#results\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Results</h2>\n<ol>\n<li><code>.har</code> files are saved in catalog <code>reports/performance/*.har</code></li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/parallel-testing\"><span class=\"arrow-prev\">← </span><span>Parallel testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/docker\"><span>Docker</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#get-started\">Get started</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#results\">Results</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/performance-testing.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Performance testing · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Performance testing · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Performance testing is possible thanks to `browsermob-proxy`.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Features</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Performance testing</h1></header><article><div><span><p>Performance testing is possible thanks to <code>browsermob-proxy</code>.</p>\n<p>It saves all data from network tab (Google Chrome console) which is generated during the test.</p>\n<p>There is a possibility to compare <code>TTFB</code> value with a maximum given one.</p>\n<p><code>TTFB</code> (Time to first byte) measures the duration from the client making an HTTP request to the first byte of a response being received by the client's browser.</p>\n<p>More details can be found in documentation - <code>Built-in steps</code> section.</p>\n<h1><a class=\"anchor\" aria-hidden=\"true\" id=\"what-needs-to-be-done\"></a><a href=\"#what-needs-to-be-done\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What needs to be done?</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"get-started\"></a><a href=\"#get-started\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get started</h2>\n<ol>\n<li><p>Download <code>browsermob-proxy</code> from <code>https://github.com/lightbody/browsermob-proxy</code></p></li>\n<li><p>Navigate in terminal to the catalog</p></li>\n<li><p>Use following command to start the REST API</p></li>\n</ol>\n<pre><code class=\"hljs\">./browsermob-proxy -port <span class=\"hljs-number\">8887</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configuration\"></a><a href=\"#configuration\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuration</h2>\n<ol>\n<li>Add <code>browsermob-proxy</code> configuration to <code>kakunin.conf.js</code></li>\n</ol>\n<p>You can use one of the following methods to configure browsermob-proxy:</p>\n<ul>\n<li><p><code>npm run kakunin init -- --advanced</code> and go through the process</p></li>\n<li><p>or add it manually to the config file:</p></li>\n</ul>\n<pre><code class=\"hljs css language-javascript\">    <span class=\"hljs-string\">\"browserMob\"</span>: {\n      <span class=\"hljs-string\">\"serverPort\"</span>: <span class=\"hljs-number\">8887</span>,\n      <span class=\"hljs-string\">\"port\"</span>: <span class=\"hljs-number\">8888</span>,\n      <span class=\"hljs-string\">\"host\"</span>: <span class=\"hljs-string\">\"localhost\"</span>\n    }\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"run-tests\"></a><a href=\"#run-tests\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run tests</h2>\n<ol>\n<li><p><code>performance steps</code> must be used in the scenario where you are testing performance</p></li>\n<li><p>Scenario must have a tag <code>@performance</code></p></li>\n<li><p>Run tests with special parameter:</p></li>\n</ol>\n<pre><code class=\"hljs\">npm <span class=\"hljs-built_in\">run</span> kakunin <span class=\"hljs-comment\">-- --performance</span>\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"results\"></a><a href=\"#results\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Results</h2>\n<ol>\n<li><code>.har</code> files are saved in catalog <code>reports/performance/*.har</code></li>\n</ol>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/parallel-testing\"><span class=\"arrow-prev\">← </span><span>Parallel testing</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/docker\"><span>Docker</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#get-started\">Get started</a></li><li><a href=\"#configuration\">Configuration</a></li><li><a href=\"#run-tests\">Run tests</a></li><li><a href=\"#results\">Results</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/quickstart/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Quick start · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Quick start · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Quick start</h1></header><article><div><span><p>As a quick demonstration of the framework let's test the\n<a href=\"http://todomvc.com/examples/react/#/\">React variant of TodoMVC</a> project.\nOf course other testing other frameworks is possible, you can try it\nby yourself!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"install-packages\"></a><a href=\"#install-packages\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install packages</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project and enter it</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-variable\">$mkdir</span> my_project\n<span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env protractor webdriver-manager kakunin  --save\n</code></pre>\n<p>Inside <code>package.json</code> file add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-js\">...\n<span class=\"hljs-string\">\"scripts\"</span>: {\n  <span class=\"hljs-string\">\"kakunin\"</span>: <span class=\"hljs-string\">\"cross-env NODE_ENV=prod kakunin\"</span>\n},\n...\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configure-kakunin\"></a><a href=\"#configure-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure Kakunin</h2>\n<p>Run initialization command</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>Answer literally few questions:</p>\n<pre><code class=\"hljs css language-text\">What kind of application would you like to test? : otherWeb\n        \nWhat is base url? [http://localhost:3000]: http://todomvc.com\n           \nWhat kind of email service would you like to use?: none\n</code></pre>\n<p>And you're set! Now let's write some test!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"test-the-app\"></a><a href=\"#test-the-app\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the app</h2>\n<p>Create a page object that will contain instructions on how to locate elements in the projects.\nCreate a file <code>pages/main.js</code>:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MainPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n\n        <span class=\"hljs-comment\">// define the main url for the page</span>\n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/examples/react/#/'</span>;\n\n        <span class=\"hljs-comment\">// whole form tag</span>\n        <span class=\"hljs-keyword\">this</span>.addTodoForm = $(<span class=\"hljs-string\">'.todoapp'</span>);\n\n        <span class=\"hljs-comment\">// input field</span>\n        <span class=\"hljs-keyword\">this</span>.todoInput = $(<span class=\"hljs-string\">'input.new-todo'</span>);\n\n        <span class=\"hljs-comment\">// list of currently added todos</span>\n        <span class=\"hljs-keyword\">this</span>.todos = $$(<span class=\"hljs-string\">'.todo-list .view'</span>);\n        <span class=\"hljs-keyword\">this</span>.todoLabel = by.css(<span class=\"hljs-string\">'label'</span>);\n\n        <span class=\"hljs-comment\">// first todo item in a list</span>\n        <span class=\"hljs-keyword\">this</span>.firstTodoItem = <span class=\"hljs-keyword\">this</span>.todos.get(<span class=\"hljs-number\">0</span>);\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MainPage;\n</code></pre>\n<p>Now that we have prepared the locators, we can start writing our test. Let's test adding new todo item.</p>\n<p>Create a file named: <code>features/adding_todo.feature</code> with the following contents:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 1\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n\n</code></pre>\n<p>And that's it! All you have to do now is to run the test and watch the magic happens ;)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<p>The tests may run quite fast so you might not been able to see that it\nreally works as expected. To check if the todo items has been really\nadded to the list, let's use a simple hack - let's pause the running\ntest right after the todo has been added.</p>\n<p>To do that, let's upgrade our Scenario. Update the file:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> Another todo item! </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 2\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n        <span class=\"hljs-keyword\">Then</span> I wait for <span class=\"hljs-string\">\"5\"</span> seconds\n\n</code></pre>\n<p>As you can see, we've added 1 new step that waits for a second before\n&quot;pressing&quot; the <code>enter</code> key. We've also added a second todo item with\na short pause at the end of the test so you can see the changes.</p>\n<p>If you want to see what can we do more with the TodoMVC project, take a look\nat the <code>example</code> dir, where you'll find a complete set of test for the project.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-next button\" href=\"/Kakunin/docs/index\"><span>Getting started</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#install-packages\">Install packages</a></li><li><a href=\"#configure-kakunin\">Configure Kakunin</a></li><li><a href=\"#test-the-app\">Test the app</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/quickstart.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Quick start · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Quick start · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"As a quick demonstration of the framework let&#x27;s test the \"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Documentation</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Quick start</h1></header><article><div><span><p>As a quick demonstration of the framework let's test the\n<a href=\"http://todomvc.com/examples/react/#/\">React variant of TodoMVC</a> project.\nOf course other testing other frameworks is possible, you can try it\nby yourself!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"install-packages\"></a><a href=\"#install-packages\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install packages</h2>\n<p>In order to install Kakunin you have to make sure that you have installed:</p>\n<pre><code class=\"hljs css language-text\">node.js - v7.8.0 min\nJDK\nChrome\n</code></pre>\n<p>Create directory for your project and enter it</p>\n<pre><code class=\"hljs css language-bash\"><span class=\"hljs-variable\">$mkdir</span> my_project\n<span class=\"hljs-built_in\">cd</span> my_project\n</code></pre>\n<p>Initialize JavaScript project</p>\n<pre><code class=\"hljs css language-bash\">npm init\n</code></pre>\n<p>Install dependencies</p>\n<pre><code class=\"hljs css language-bash\">npm install cross-env protractor webdriver-manager kakunin  --save\n</code></pre>\n<p>Inside <code>package.json</code> file add new script in <code>scripts</code> section:</p>\n<pre><code class=\"hljs css language-js\">...\n<span class=\"hljs-string\">\"scripts\"</span>: {\n  <span class=\"hljs-string\">\"kakunin\"</span>: <span class=\"hljs-string\">\"cross-env NODE_ENV=prod kakunin\"</span>\n},\n...\n</code></pre>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"configure-kakunin\"></a><a href=\"#configure-kakunin\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure Kakunin</h2>\n<p>Run initialization command</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin init\n</code></pre>\n<p>Answer literally few questions:</p>\n<pre><code class=\"hljs css language-text\">What kind of application would you like to test? : otherWeb\n        \nWhat is base url? [http://localhost:3000]: http://todomvc.com\n           \nWhat kind of email service would you like to use?: none\n</code></pre>\n<p>And you're set! Now let's write some test!</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"test-the-app\"></a><a href=\"#test-the-app\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test the app</h2>\n<p>Create a page object that will contain instructions on how to locate elements in the projects.\nCreate a file <code>pages/main.js</code>:</p>\n<pre><code class=\"hljs css language-javascript\"><span class=\"hljs-keyword\">const</span> { BasePage } = <span class=\"hljs-built_in\">require</span>(<span class=\"hljs-string\">'kakunin'</span>);\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MainPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">BasePage</span> </span>{\n    <span class=\"hljs-keyword\">constructor</span>() {\n        <span class=\"hljs-keyword\">super</span>();\n\n        <span class=\"hljs-comment\">// define the main url for the page</span>\n        <span class=\"hljs-keyword\">this</span>.url = <span class=\"hljs-string\">'/examples/react/#/'</span>;\n\n        <span class=\"hljs-comment\">// whole form tag</span>\n        <span class=\"hljs-keyword\">this</span>.addTodoForm = $(<span class=\"hljs-string\">'.todoapp'</span>);\n\n        <span class=\"hljs-comment\">// input field</span>\n        <span class=\"hljs-keyword\">this</span>.todoInput = $(<span class=\"hljs-string\">'input.new-todo'</span>);\n\n        <span class=\"hljs-comment\">// list of currently added todos</span>\n        <span class=\"hljs-keyword\">this</span>.todos = $$(<span class=\"hljs-string\">'.todo-list .view'</span>);\n        <span class=\"hljs-keyword\">this</span>.todoLabel = by.css(<span class=\"hljs-string\">'label'</span>);\n\n        <span class=\"hljs-comment\">// first todo item in a list</span>\n        <span class=\"hljs-keyword\">this</span>.firstTodoItem = <span class=\"hljs-keyword\">this</span>.todos.get(<span class=\"hljs-number\">0</span>);\n    }\n}\n\n<span class=\"hljs-built_in\">module</span>.exports = MainPage;\n</code></pre>\n<p>Now that we have prepared the locators, we can start writing our test. Let's test adding new todo item.</p>\n<p>Create a file named: <code>features/adding_todo.feature</code> with the following contents:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 1\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n\n</code></pre>\n<p>And that's it! All you have to do now is to run the test and watch the magic happens ;)</p>\n<pre><code class=\"hljs css language-bash\">npm run kakunin\n</code></pre>\n<p>The tests may run quite fast so you might not been able to see that it\nreally works as expected. To check if the todo items has been really\nadded to the list, let's use a simple hack - let's pause the running\ntest right after the todo has been added.</p>\n<p>To do that, let's upgrade our Scenario. Update the file:</p>\n<pre><code class=\"hljs css language-gherkin\"><span class=\"hljs-keyword\">Feature</span>:\n\n    <span class=\"hljs-keyword\">Scenario</span>: Adding todo\n        <span class=\"hljs-keyword\">Given</span> I visit the <span class=\"hljs-string\">\"main\"</span> page\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"visibilityOf\"</span> of the <span class=\"hljs-string\">\"addTodoForm\"</span> element\n        <span class=\"hljs-keyword\">And</span> the <span class=\"hljs-string\">\"addTodoForm\"</span> element is visible\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> My new todo </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">When</span> I fill the <span class=\"hljs-string\">\"addTodoForm\"</span> form with:\n            |<span class=\"hljs-string\"> todoInput </span>|<span class=\"hljs-string\"> Another todo item! </span>|\n        <span class=\"hljs-keyword\">And</span> I wait for <span class=\"hljs-string\">\"1\"</span> seconds\n        <span class=\"hljs-keyword\">And</span> I press the <span class=\"hljs-string\">\"enter\"</span> key\n        <span class=\"hljs-keyword\">Then</span> there are <span class=\"hljs-string\">\"equal 2\"</span> <span class=\"hljs-string\">\"todos\"</span> elements\n        <span class=\"hljs-keyword\">Then</span> I wait for <span class=\"hljs-string\">\"5\"</span> seconds\n\n</code></pre>\n<p>As you can see, we've added 1 new step that waits for a second before\n&quot;pressing&quot; the <code>enter</code> key. We've also added a second todo item with\na short pause at the end of the test so you can see the changes.</p>\n<p>If you want to see what can we do more with the TodoMVC project, take a look\nat the <code>example</code> dir, where you'll find a complete set of test for the project.</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-next button\" href=\"/Kakunin/docs/index\"><span>Getting started</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#install-packages\">Install packages</a></li><li><a href=\"#configure-kakunin\">Configure Kakunin</a></li><li><a href=\"#test-the-app\">Test the app</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-debug/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Debug · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps for debugging application:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Debug · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps for debugging application:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Debug</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-for-debugging-application\"></a><a href=\"#steps-for-debugging-application\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps for debugging application:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-pause\"></a><a href=\"#i-pause\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I pause</code></h2>\n<p>Pauses tests execution and allows to continue manually by pressing combination of <code>ctrl+c</code> inside terminal.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-seconds-seconds\"></a><a href=\"#i-wait-for-seconds-seconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:seconds&quot; seconds</code></h2>\n<p>Waits with execution of next step for an amount provided by parameter <code>:seconds</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-start-performance-monitor-mode\"></a><a href=\"#i-start-performance-monitor-mode\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I start performance monitor mode</code></h2>\n<p>It starts performance monitor mode.</p>\n<p>Keep in mind that REST API must be started on the port which must configured in <code>kakunin.conf.js</code> - <code>serverPort: 8887</code>.</p>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-save-performance-report-file-as-filename\"></a><a href=\"#i-save-performance-report-file-as-filename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I save performance report file as &quot;fileName&quot;</code></h2>\n<p>It saves <code>.har</code> file with a name <code>fileName</code> in <code>reports/performance</code> catalog.</p>\n<p>For example: <code>exampleReport-1511470954552.har</code></p>\n<p>Data is generated during the test - network tab in Chrome Chrome console.</p>\n<p>Keep in mind:</p>\n<ul>\n<li><p><code>I start performance monitor mode</code> must be used before this step</p></li>\n<li><p><code>browserMob.port</code> must be configured in <code>kakunin.conf.js</code></p></li>\n<li><p><code>browserMob.host</code> must be configured in <code>kakunin.conf.js</code></p></li>\n</ul>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"></a><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></h2>\n<p>It compares every <code>TTFB</code> timing value from previously saved <code>.har</code> report with a <code>maxTiming</code> value.</p>\n<p>Slow requests are listed in your terminal in red colour.</p>\n<p>Keep in mind that <code>I start performance monitor mode</code> and <code>I save performance report file as &quot;fileName&quot;</code> steps must be executed before this one!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-generators\"><span class=\"arrow-prev\">← </span><span>Generators</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-pause\"><code>I pause</code></a></li><li><a href=\"#i-wait-for-seconds-seconds\"><code>I wait for &quot;:seconds&quot; seconds</code></a></li><li><a href=\"#i-start-performance-monitor-mode\"><code>I start performance monitor mode</code></a></li><li><a href=\"#i-save-performance-report-file-as-filename\"><code>I save performance report file as &quot;fileName&quot;</code></a></li><li><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-debug.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Debug · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps for debugging application:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Debug · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps for debugging application:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Debug</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-for-debugging-application\"></a><a href=\"#steps-for-debugging-application\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps for debugging application:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-pause\"></a><a href=\"#i-pause\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I pause</code></h2>\n<p>Pauses tests execution and allows to continue manually by pressing combination of <code>ctrl+c</code> inside terminal.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-seconds-seconds\"></a><a href=\"#i-wait-for-seconds-seconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:seconds&quot; seconds</code></h2>\n<p>Waits with execution of next step for an amount provided by parameter <code>:seconds</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-start-performance-monitor-mode\"></a><a href=\"#i-start-performance-monitor-mode\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I start performance monitor mode</code></h2>\n<p>It starts performance monitor mode.</p>\n<p>Keep in mind that REST API must be started on the port which must configured in <code>kakunin.conf.js</code> - <code>serverPort: 8887</code>.</p>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-save-performance-report-file-as-filename\"></a><a href=\"#i-save-performance-report-file-as-filename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I save performance report file as &quot;fileName&quot;</code></h2>\n<p>It saves <code>.har</code> file with a name <code>fileName</code> in <code>reports/performance</code> catalog.</p>\n<p>For example: <code>exampleReport-1511470954552.har</code></p>\n<p>Data is generated during the test - network tab in Chrome Chrome console.</p>\n<p>Keep in mind:</p>\n<ul>\n<li><p><code>I start performance monitor mode</code> must be used before this step</p></li>\n<li><p><code>browserMob.port</code> must be configured in <code>kakunin.conf.js</code></p></li>\n<li><p><code>browserMob.host</code> must be configured in <code>kakunin.conf.js</code></p></li>\n</ul>\n<p>More details can be found in documentation file <code>performance-testing.md</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"></a><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></h2>\n<p>It compares every <code>TTFB</code> timing value from previously saved <code>.har</code> report with a <code>maxTiming</code> value.</p>\n<p>Slow requests are listed in your terminal in red colour.</p>\n<p>Keep in mind that <code>I start performance monitor mode</code> and <code>I save performance report file as &quot;fileName&quot;</code> steps must be executed before this one!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-generators\"><span class=\"arrow-prev\">← </span><span>Generators</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-pause\"><code>I pause</code></a></li><li><a href=\"#i-wait-for-seconds-seconds\"><code>I wait for &quot;:seconds&quot; seconds</code></a></li><li><a href=\"#i-start-performance-monitor-mode\"><code>I start performance monitor mode</code></a></li><li><a href=\"#i-save-performance-report-file-as-filename\"><code>I save performance report file as &quot;fileName&quot;</code></a></li><li><a href=\"#the-requests-should-take-a-maximum-of-maxtiming-milliseconds\"><code>the requests should take a maximum of &quot;maxTiming&quot; milliseconds</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-elements/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Elements · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with elements:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Elements · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with elements:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Elements</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-elements\"></a><a href=\"#steps-used-to-interact-with-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with elements:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll through infinite scroll mechanism.</p>\n<p>The <code>:elementName</code> is a name of a selector for loading trigger.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-expectedconditionname-of-the-elementname-element\"></a><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></h2>\n<p>Waits till element <code>:elementName</code> from <code>this.currentPage</code> meets criteria specified by <code>:expectedConditionName</code>.</p>\n<p>You can use any of the Protractor's expected condition:</p>\n<ul>\n<li><code>visibilityOf</code></li>\n<li><code>invisibilityOf</code></li>\n</ul>\n<p>etc.</p>\n<p>Read more in Protractor's API documentation.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-the-elementname-element-to-disappear\"></a><a href=\"#i-wait-for-the-elementname-element-to-disappear\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for the &quot;:elementName&quot; element to disappear</code></h2>\n<p>Waits till element <code>:elementName</code> disappears.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-scroll-to-the-elementname-element\"></a><a href=\"#i-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Scrolls to element <code>:elementName</code> of <code>this.currentPage</code>. The element will be on bottom of the page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element-1\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll till <code>:elementName</code> is visible. Useful for infinite scrolling functionality.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-press-the-keyname-key\"></a><a href=\"#i-press-the-keyname-key\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I press the &quot;:keyName&quot; key</code></h2>\n<p>Performs a key press operation on <code>:keyName</code> key.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-click-the-elementname-element\"></a><a href=\"#i-click-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I click the &quot;:elementName&quot; element</code></h2>\n<p>Performs a click action on element <code>:elementName</code> from `this.currentPage'</p>\n<p>The child element must be specified by <code>:elementName</code> and must be available in <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the text from element <code>:elementName</code> of <code>this.currentPage</code> under the <code>:variableName</code> so you can use it later.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-update-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Updates the variable <code>:variableName</code> value by value from element <code>:elementName</code> of <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the part of the element <code>:elementName</code> text, that matches the <code>:matchingRegex</code> under the <code>:variableName</code> for later use.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-visible\"></a><a href=\"#the-elementname-element-is-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is visible</code></h2>\n<p>Checks if element <code>:elementName</code> is visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-not-visible\"></a><a href=\"#the-elementname-element-is-not-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is not visible</code></h2>\n<p>Checks if element <code>:elementName</code> is available in HTML DOM but is not visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-disabled\"></a><a href=\"#the-elementname-element-is-disabled\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot; element is disabled</code></h2>\n<p>Checks if element is disabled</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-table-tablerow-rows-as-variablename-with-columns\"></a><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></h2>\n<p>Allows to store a row specified columns from a table <code>:tableRow</code> and save it under <code>:variableName</code> as an array of objects.</p>\n<p>This step requires a table of columns elements, for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I store table <span class=\"hljs-string\">\"someRow\"</span> rows as <span class=\"hljs-string\">\"someVariable\"</span> with columns:\n  |<span class=\"hljs-string\"> firstName </span>|\n  |<span class=\"hljs-string\"> lastName  </span>|\n  |<span class=\"hljs-string\"> id        </span>|\n</code></pre>\n<p>In order to make it work there must be not only array element <code>this.someRow = $$('.rows')</code> in <code>this.currentPage</code>, but also\nelement <code>this.firstName = $('.firstName');</code> and so on.</p>\n<p>The result of this step is an array of:</p>\n<pre><code class=\"hljs css language-javascript\">[\n  [\n    <span class=\"hljs-string\">'firsRowFirstNameValue'</span>,\n    <span class=\"hljs-string\">'firsRowLastNameValue'</span>\n    <span class=\"hljs-string\">'firsRowIdValue'</span>\n  ]\n  ...\n]\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-following-elements-in-table-elementname\"></a><a href=\"#there-are-following-elements-in-table-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are following elements in table &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content.</p>\n<p>This steps allows you to specify an array of child elements that will be checked against expected values.</p>\n<p>For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are following elements in table <span class=\"hljs-string\">\"myTable\"</span>:\n  |<span class=\"hljs-string\"> id  </span>|<span class=\"hljs-string\"> firstName </span>|<span class=\"hljs-string\"> lastName </span>|\n  |<span class=\"hljs-string\"> t:1 </span>|<span class=\"hljs-string\"> t:Adam    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n  |<span class=\"hljs-string\"> t:2 </span>|<span class=\"hljs-string\"> t:John    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n</code></pre>\n<p>First row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.</p>\n<p>This step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.</p>\n<p>We can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-following-elements-for-element-elementname\"></a><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>Allows to check if a number of elements is the one that we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are <span class=\"hljs-string\">\"equal 5\"</span> following elements for element <span class=\"hljs-string\">\"myList\"</span>:\n  |<span class=\"hljs-string\"> viewButton </span>|<span class=\"hljs-string\"> f:isClickable </span>|\n  |<span class=\"hljs-string\"> id         </span>|<span class=\"hljs-string\"> r:idRegex     </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.viewButton = $('button.viewButton');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-value-matcher\"></a><a href=\"#there-is-element-elementname-with-value-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> has a value that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-containing-matcher-text\"></a><a href=\"#there-is-element-elementname-containing-matcher-text\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></h2>\n<p>Allows to check if <code>:elementName</code> contains a text that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-matching-matcher-matcher\"></a><a href=\"#there-is-element-elementname-matching-matcher-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></h2>\n<p>Allows to check if <code>:elementName</code> matches the given type of <code>:matcher</code>. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there is element <span class=\"hljs-string\">\"button\"</span> matching <span class=\"hljs-string\">\"isClickable\"</span> matcher\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-regex-matcher\"></a><a href=\"#there-is-element-elementname-with-regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> matches given type of regex. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there is element <span class=\"hljs-string\">\"input\"</span> with regex <span class=\"hljs-string\">\"notEmpty\"</span>\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-value-matchername\"></a><a href=\"#there-is-no-element-elementname-with-value-matchername\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></h2>\n<p>Allows to check if there is no <code>:elementName</code> that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-containing-matcher-text\"></a><a href=\"#there-is-no-element-elementname-containing-matcher-text\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></h2>\n<p>Allows to check if <code>:elementName</code> doesn't contain a text that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-matching-matcher-matcher\"></a><a href=\"#there-is-no-element-elementname-matching-matcher-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></h2>\n<p>Allows to check if <code>:elementName</code> is not matching the given type of <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-regex-matcher\"></a><a href=\"#there-is-no-element-elementname-with-regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> is not matching given type of regex.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-elementname-elements\"></a><a href=\"#there-are-numberexpression-elementname-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></h2>\n<p>Allows to check if a number of <code>:elementName</code> elements is the same as we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p><code>:elementName</code> should be specified as an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"every-elementname-element-should-have-the-same-value-for-element-columnelementname\"></a><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></h2>\n<p>Allows to check if every row defined by <code>:elementName</code> has the same value for a column <code>:columnElementName</code>.</p>\n<p><code>:elementName</code> must be an array of elements</p>\n<p><code>:columnElementName</code> must be an element, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code> and we can specify column element\n<code>this.myColumn = $('td');</code>. This allows us to write:</p>\n<p><code>every &quot;myElement&quot; element should have the same value for element &quot;myColumn&quot;</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should have an item with values:</code></h2>\n<p>Allows to check if any of the child elements of <code>:elementName</code> have a specified content (one matching element is enough). Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:1 </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-not-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-not-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should not have an item with values:</code></h2>\n<p>Allows to check if the child elements of <code>:elementName</code> have a different content than that given in the table. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:does-not-exist </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-drag-elementdrag-element-and-drop-over-elementdrop-element\"></a><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></h2>\n<p>Clicks on <code>:elementDrag</code> and moves it onto <code>:elementDrop</code> while left mouse button is pressed, and then release it.</p>\n<p>Note: This step is not working on HTML5!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-forms\"><span class=\"arrow-prev\">← </span><span>Forms</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-files\"><span>Files</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-infinitely-scroll-to-the-elementname-element\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\"><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-the-elementname-element-to-disappear\"><code>I wait for the &quot;:elementName&quot; element to disappear</code></a></li><li><a href=\"#i-scroll-to-the-elementname-element\"><code>I scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-press-the-keyname-key\"><code>I press the &quot;:keyName&quot; key</code></a></li><li><a href=\"#i-click-the-elementname-element\"><code>I click the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\"><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#the-elementname-element-is-visible\"><code>the &quot;:elementName&quot;&quot; element is visible</code></a></li><li><a href=\"#the-elementname-element-is-not-visible\"><code>the &quot;:elementName&quot;&quot; element is not visible</code></a></li><li><a href=\"#the-elementname-element-is-disabled\"><code>the &quot;:elementName&quot; element is disabled</code></a></li><li><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\"><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></a></li><li><a href=\"#there-are-following-elements-in-table-elementname\"><code>there are following elements in table &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\"><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-is-element-elementname-with-value-matcher\"><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-element-elementname-containing-matcher-text\"><code>there is element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></a></li><li><a href=\"#there-is-element-elementname-matching-matcher-matcher\"><code>there is element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></a></li><li><a href=\"#there-is-element-elementname-with-regex-matcher\"><code>there is element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-with-value-matchername\"><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-containing-matcher-text\"><code>there is no element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></a></li><li><a href=\"#there-is-no-element-elementname-matching-matcher-matcher\"><code>there is no element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></a></li><li><a href=\"#there-is-no-element-elementname-with-regex-matcher\"><code>there is no element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></a></li><li><a href=\"#there-are-numberexpression-elementname-elements\"><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></a></li><li><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\"><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></a></li><li><a href=\"#the-element-elementname-should-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should have an item with values:</code></a></li><li><a href=\"#the-element-elementname-should-not-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should not have an item with values:</code></a></li><li><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\"><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-elements.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Elements · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with elements:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Elements · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with elements:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Elements</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-elements\"></a><a href=\"#steps-used-to-interact-with-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with elements:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll through infinite scroll mechanism.</p>\n<p>The <code>:elementName</code> is a name of a selector for loading trigger.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-expectedconditionname-of-the-elementname-element\"></a><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></h2>\n<p>Waits till element <code>:elementName</code> from <code>this.currentPage</code> meets criteria specified by <code>:expectedConditionName</code>.</p>\n<p>You can use any of the Protractor's expected condition:</p>\n<ul>\n<li><code>visibilityOf</code></li>\n<li><code>invisibilityOf</code></li>\n</ul>\n<p>etc.</p>\n<p>Read more in Protractor's API documentation.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-wait-for-the-elementname-element-to-disappear\"></a><a href=\"#i-wait-for-the-elementname-element-to-disappear\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I wait for the &quot;:elementName&quot; element to disappear</code></h2>\n<p>Waits till element <code>:elementName</code> disappears.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-scroll-to-the-elementname-element\"></a><a href=\"#i-scroll-to-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Scrolls to element <code>:elementName</code> of <code>this.currentPage</code>. The element will be on bottom of the page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-infinitely-scroll-to-the-elementname-element-1\"></a><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I infinitely scroll to the &quot;:elementName&quot; element</code></h2>\n<p>Allows to scroll till <code>:elementName</code> is visible. Useful for infinite scrolling functionality.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-press-the-keyname-key\"></a><a href=\"#i-press-the-keyname-key\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I press the &quot;:keyName&quot; key</code></h2>\n<p>Performs a key press operation on <code>:keyName</code> key.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-click-the-elementname-element\"></a><a href=\"#i-click-the-elementname-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I click the &quot;:elementName&quot; element</code></h2>\n<p>Performs a click action on element <code>:elementName</code> from `this.currentPage'</p>\n<p>The child element must be specified by <code>:elementName</code> and must be available in <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the text from element <code>:elementName</code> of <code>this.currentPage</code> under the <code>:variableName</code> so you can use it later.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-update-the-elementname-element-text-as-variablename-variable\"></a><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></h2>\n<p>Updates the variable <code>:variableName</code> value by value from element <code>:elementName</code> of <code>this.currentPage</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"></a><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></h2>\n<p>Stores the part of the element <code>:elementName</code> text, that matches the <code>:matchingRegex</code> under the <code>:variableName</code> for later use.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-visible\"></a><a href=\"#the-elementname-element-is-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is visible</code></h2>\n<p>Checks if element <code>:elementName</code> is visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-not-visible\"></a><a href=\"#the-elementname-element-is-not-visible\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot;&quot; element is not visible</code></h2>\n<p>Checks if element <code>:elementName</code> is available in HTML DOM but is not visible and clickable</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-elementname-element-is-disabled\"></a><a href=\"#the-elementname-element-is-disabled\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:elementName&quot; element is disabled</code></h2>\n<p>Checks if element is disabled</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-store-table-tablerow-rows-as-variablename-with-columns\"></a><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></h2>\n<p>Allows to store a row specified columns from a table <code>:tableRow</code> and save it under <code>:variableName</code> as an array of objects.</p>\n<p>This step requires a table of columns elements, for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I store table <span class=\"hljs-string\">\"someRow\"</span> rows as <span class=\"hljs-string\">\"someVariable\"</span> with columns:\n  |<span class=\"hljs-string\"> firstName </span>|\n  |<span class=\"hljs-string\"> lastName  </span>|\n  |<span class=\"hljs-string\"> id        </span>|\n</code></pre>\n<p>In order to make it work there must be not only array element <code>this.someRow = $$('.rows')</code> in <code>this.currentPage</code>, but also\nelement <code>this.firstName = $('.firstName');</code> and so on.</p>\n<p>The result of this step is an array of:</p>\n<pre><code class=\"hljs css language-javascript\">[\n  [\n    <span class=\"hljs-string\">'firsRowFirstNameValue'</span>,\n    <span class=\"hljs-string\">'firsRowLastNameValue'</span>\n    <span class=\"hljs-string\">'firsRowIdValue'</span>\n  ]\n  ...\n]\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-following-elements-in-table-elementname\"></a><a href=\"#there-are-following-elements-in-table-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are following elements in table &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content.</p>\n<p>This steps allows you to specify an array of child elements that will be checked against expected values.</p>\n<p>For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are following elements in table <span class=\"hljs-string\">\"myTable\"</span>:\n  |<span class=\"hljs-string\"> id  </span>|<span class=\"hljs-string\"> firstName </span>|<span class=\"hljs-string\"> lastName </span>|\n  |<span class=\"hljs-string\"> t:1 </span>|<span class=\"hljs-string\"> t:Adam    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n  |<span class=\"hljs-string\"> t:2 </span>|<span class=\"hljs-string\"> t:John    </span>|<span class=\"hljs-string\"> t:Doe    </span>|\n</code></pre>\n<p>First row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.</p>\n<p>This step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.</p>\n<p>We can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-following-elements-for-element-elementname\"></a><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></h2>\n<p>Allows to check if a child elements of <code>:elementName</code> have a specified content. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>Allows to check if a number of elements is the one that we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there are <span class=\"hljs-string\">\"equal 5\"</span> following elements for element <span class=\"hljs-string\">\"myList\"</span>:\n  |<span class=\"hljs-string\"> viewButton </span>|<span class=\"hljs-string\"> f:isClickable </span>|\n  |<span class=\"hljs-string\"> id         </span>|<span class=\"hljs-string\"> r:idRegex     </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.viewButton = $('button.viewButton');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-value-matcher\"></a><a href=\"#there-is-element-elementname-with-value-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> has a value that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-containing-matcher-text\"></a><a href=\"#there-is-element-elementname-containing-matcher-text\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></h2>\n<p>Allows to check if <code>:elementName</code> contains a text that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-matching-matcher-matcher\"></a><a href=\"#there-is-element-elementname-matching-matcher-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></h2>\n<p>Allows to check if <code>:elementName</code> matches the given type of <code>:matcher</code>. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there is element <span class=\"hljs-string\">\"button\"</span> matching <span class=\"hljs-string\">\"isClickable\"</span> matcher\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-element-elementname-with-regex-matcher\"></a><a href=\"#there-is-element-elementname-with-regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> matches given type of regex. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">there is element <span class=\"hljs-string\">\"input\"</span> with regex <span class=\"hljs-string\">\"notEmpty\"</span>\n</code></pre>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-value-matchername\"></a><a href=\"#there-is-no-element-elementname-with-value-matchername\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></h2>\n<p>Allows to check if there is no <code>:elementName</code> that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-containing-matcher-text\"></a><a href=\"#there-is-no-element-elementname-containing-matcher-text\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></h2>\n<p>Allows to check if <code>:elementName</code> doesn't contain a text that matches the <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-matching-matcher-matcher\"></a><a href=\"#there-is-no-element-elementname-matching-matcher-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></h2>\n<p>Allows to check if <code>:elementName</code> is not matching the given type of <code>:matcher</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-is-no-element-elementname-with-regex-matcher\"></a><a href=\"#there-is-no-element-elementname-with-regex-matcher\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there is no element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></h2>\n<p>Allows to check if <code>:elementName</code> is not matching given type of regex.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"there-are-numberexpression-elementname-elements\"></a><a href=\"#there-are-numberexpression-elementname-elements\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></h2>\n<p>Allows to check if a number of <code>:elementName</code> elements is the same as we expect.</p>\n<p><code>numberExpression</code> is a supported expression from <code>chai.js</code> library:</p>\n<ul>\n<li><p><code>equal N</code> where N is a number</p></li>\n<li><p><code>at least N</code> where N is a number</p></li>\n<li><p><code>above N</code> where N is a number</p></li>\n<li><p><code>below N</code> where N is a number</p></li>\n<li><p><code>within N M</code> where N and M are a numbers</p></li>\n</ul>\n<p>and so on. You can check expressions on <code>chai.js</code> API dock for BDD.</p>\n<p><code>:elementName</code> should be specified as an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"every-elementname-element-should-have-the-same-value-for-element-columnelementname\"></a><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></h2>\n<p>Allows to check if every row defined by <code>:elementName</code> has the same value for a column <code>:columnElementName</code>.</p>\n<p><code>:elementName</code> must be an array of elements</p>\n<p><code>:columnElementName</code> must be an element, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code> and we can specify column element\n<code>this.myColumn = $('td');</code>. This allows us to write:</p>\n<p><code>every &quot;myElement&quot; element should have the same value for element &quot;myColumn&quot;</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should have an item with values:</code></h2>\n<p>Allows to check if any of the child elements of <code>:elementName</code> have a specified content (one matching element is enough). Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:1 </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-element-elementname-should-not-have-an-item-with-values\"></a><a href=\"#the-element-elementname-should-not-have-an-item-with-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the element &quot;:elementName&quot; should not have an item with values:</code></h2>\n<p>Allows to check if the child elements of <code>:elementName</code> have a different content than that given in the table. Element should be an array, for example:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td</span>&gt;</span>2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">td</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">tr</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">table</span>&gt;</span>\n</code></pre>\n<p>for this case the <code>:elementName</code> should be specified as <code>$$('table tr')</code>.</p>\n<p>This step requires an array of elements to be checked. For example:</p>\n<pre><code class=\"hljs css language-gherkin\">the element <span class=\"hljs-string\">\"myList\"</span> should have an item with values:\n  |<span class=\"hljs-string\"> id </span>|<span class=\"hljs-string\"> t:does-not-exist </span>|\n</code></pre>\n<p>The child elements must be an elements, for example <code>this.id = $('td');</code>.</p>\n<p>You can use all kind of matchers here.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-drag-elementdrag-element-and-drop-over-elementdrop-element\"></a><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></h2>\n<p>Clicks on <code>:elementDrag</code> and moves it onto <code>:elementDrop</code> while left mouse button is pressed, and then release it.</p>\n<p>Note: This step is not working on HTML5!</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-forms\"><span class=\"arrow-prev\">← </span><span>Forms</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-files\"><span>Files</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-infinitely-scroll-to-the-elementname-element\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-expectedconditionname-of-the-elementname-element\"><code>I wait for &quot;:expectedConditionName&quot; of the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-wait-for-the-elementname-element-to-disappear\"><code>I wait for the &quot;:elementName&quot; element to disappear</code></a></li><li><a href=\"#i-scroll-to-the-elementname-element\"><code>I scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-infinitely-scroll-to-the-elementname-element-1\"><code>I infinitely scroll to the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-press-the-keyname-key\"><code>I press the &quot;:keyName&quot; key</code></a></li><li><a href=\"#i-click-the-elementname-element\"><code>I click the &quot;:elementName&quot; element</code></a></li><li><a href=\"#i-store-the-elementname-element-text-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-update-the-elementname-element-text-as-variablename-variable\"><code>I update the &quot;:elementName&quot; element text as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#i-store-the-elementname-element-text-matched-by-matchingregex-as-variablename-variable\"><code>I store the &quot;:elementName&quot; element text matched by &quot;:matchingRegex&quot; as &quot;:variableName&quot; variable</code></a></li><li><a href=\"#the-elementname-element-is-visible\"><code>the &quot;:elementName&quot;&quot; element is visible</code></a></li><li><a href=\"#the-elementname-element-is-not-visible\"><code>the &quot;:elementName&quot;&quot; element is not visible</code></a></li><li><a href=\"#the-elementname-element-is-disabled\"><code>the &quot;:elementName&quot; element is disabled</code></a></li><li><a href=\"#i-store-table-tablerow-rows-as-variablename-with-columns\"><code>I store table &quot;:tableRow&quot; rows as &quot;:variableName&quot; with columns:</code></a></li><li><a href=\"#there-are-following-elements-in-table-elementname\"><code>there are following elements in table &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-are-numberexpression-following-elements-for-element-elementname\"><code>there are &quot;numberExpression&quot; following elements for element &quot;:elementName&quot;:</code></a></li><li><a href=\"#there-is-element-elementname-with-value-matcher\"><code>there is element &quot;:elementName&quot; with value &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-element-elementname-containing-matcher-text\"><code>there is element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></a></li><li><a href=\"#there-is-element-elementname-matching-matcher-matcher\"><code>there is element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></a></li><li><a href=\"#there-is-element-elementname-with-regex-matcher\"><code>there is element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-with-value-matchername\"><code>there is no element &quot;:elementName&quot; with value &quot;:matcherName&quot;</code></a></li><li><a href=\"#there-is-no-element-elementname-containing-matcher-text\"><code>there is no element &quot;:elementName&quot; containing &quot;:matcher&quot; text</code></a></li><li><a href=\"#there-is-no-element-elementname-matching-matcher-matcher\"><code>there is no element &quot;:elementName&quot; matching &quot;:matcher&quot; matcher</code></a></li><li><a href=\"#there-is-no-element-elementname-with-regex-matcher\"><code>there is no element &quot;:elementName&quot; with regex &quot;:matcher&quot;</code></a></li><li><a href=\"#there-are-numberexpression-elementname-elements\"><code>there are &quot;numberExpression&quot; &quot;:elementName&quot; elements</code></a></li><li><a href=\"#every-elementname-element-should-have-the-same-value-for-element-columnelementname\"><code>every &quot;:elementName&quot; element should have the same value for element &quot;:columnElementName&quot;</code></a></li><li><a href=\"#the-element-elementname-should-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should have an item with values:</code></a></li><li><a href=\"#the-element-elementname-should-not-have-an-item-with-values\"><code>the element &quot;:elementName&quot; should not have an item with values:</code></a></li><li><a href=\"#i-drag-elementdrag-element-and-drop-over-elementdrop-element\"><code>I drag &quot;:elementDrag&quot; element and drop over &quot;:elementDrop&quot; element</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-files/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Files · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with files:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Files · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with files:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Files</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-files\"></a><a href=\"#steps-used-to-interact-with-files\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with files:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-should-be-downloaded\"></a><a href=\"#the-file-filename-should-be-downloaded\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; should be downloaded</code></h2>\n<p>Checks if a file with name <code>:fileName</code> was downloaded.</p>\n<p>This step does not support matchers or regular expressions, so the name must be exact match. However you can use\nvariable store here.</p>\n<p>Let's assume there is a variable <code>myFile</code> with a value <code>super-file</code> in variable store.</p>\n<p>You can write <code>the file &quot;v:myFile.zip&quot; should be downloaded</code> to check if a file <code>super-file.zip</code> was downloaded.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-contains-table-data-stored-under-variablename-variable\"></a><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></h2>\n<p>This step allows you to compare an xls/xlsx file <code>:fileName</code> with an existing data stored under <code>:variableName</code> variable.</p>\n<p>The data under <code>:variableName</code> must be an array of objects representing each row of file.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-elements\"><span class=\"arrow-prev\">← </span><span>Elements</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-generators\"><span>Generators</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#the-file-filename-should-be-downloaded\"><code>the file &quot;:fileName&quot; should be downloaded</code></a></li><li><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\"><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-files.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Files · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to interact with files:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Files · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to interact with files:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Files</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-interact-with-files\"></a><a href=\"#steps-used-to-interact-with-files\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to interact with files:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-should-be-downloaded\"></a><a href=\"#the-file-filename-should-be-downloaded\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; should be downloaded</code></h2>\n<p>Checks if a file with name <code>:fileName</code> was downloaded.</p>\n<p>This step does not support matchers or regular expressions, so the name must be exact match. However you can use\nvariable store here.</p>\n<p>Let's assume there is a variable <code>myFile</code> with a value <code>super-file</code> in variable store.</p>\n<p>You can write <code>the file &quot;v:myFile.zip&quot; should be downloaded</code> to check if a file <code>super-file.zip</code> was downloaded.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-file-filename-contains-table-data-stored-under-variablename-variable\"></a><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></h2>\n<p>This step allows you to compare an xls/xlsx file <code>:fileName</code> with an existing data stored under <code>:variableName</code> variable.</p>\n<p>The data under <code>:variableName</code> must be an array of objects representing each row of file.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-elements\"><span class=\"arrow-prev\">← </span><span>Elements</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-generators\"><span>Generators</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#the-file-filename-should-be-downloaded\"><code>the file &quot;:fileName&quot; should be downloaded</code></a></li><li><a href=\"#the-file-filename-contains-table-data-stored-under-variablename-variable\"><code>the file &quot;:fileName&quot; contains table data stored under &quot;:variableName&quot; variable</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-forms/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Forms · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to fill forms:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Forms · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to fill forms:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Forms</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-fill-forms\"></a><a href=\"#steps-used-to-fill-forms\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to fill forms:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-fill-the-formname-form-with\"></a><a href=\"#i-fill-the-formname-form-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I fill the &quot;:formName&quot; form with:</code></h2>\n<p>Allows to fill the form with the name <code>:formName</code> and values provided as an array of inputs and values. The element with name <code>:formName</code> must be defined inside the\n<code>currentPage</code> page object.</p>\n<p>Input and values should be provided as an array for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> value to be typed into field        </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> value to be typed into textarea     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> radio value to be selected          </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> checkbox label value to be selected </span>|\n</code></pre>\n<p>By default we support all basic HTML field types (text inputs, checkboxes, radios, selects, files and textareas)</p>\n<p>In order to use the default handlers the elements you use as input must follow pattern:</p>\n<p>For inputs:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill</p>\n<p>For textareas:</p>\n<p><code>this.element = $('textarea')</code> - element should point at textarea you want to fill</p>\n<p>For file input:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill and value should a filename of file from <code>data</code> directory</p>\n<p>For selects:</p>\n<p><code>this.element = $('select')</code> - element should point at select and value should be an value of expected option</p>\n<p>For radios:</p>\n<p><code>this.element = $$('radio[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all radio input of given name and value should be an value of radio you wish to select</p>\n<p>For checkboxes:</p>\n<p>Checkbox should have a html like:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label</span>&gt;</span>\n  My checkbox\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"checkbox\"</span> <span class=\"hljs-attr\">name</span>=<span class=\"hljs-string\">\"some-name\"</span>/&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">label</span>&gt;</span>\n</code></pre>\n<p><code>this.element = $$('checkbox[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all checkboxes of given name and value should be a text from label of checkbox you want to fill</p>\n<p>You can use all kind of transformers to as a values for fields.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-formname-form-is-filled-with\"></a><a href=\"#the-formname-form-is-filled-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:formName&quot; form is filled with:</code></h2>\n<p>The same as <code>I fill the &quot;:formName&quot; form with:</code> but allows to check if a form is filled with a given set of values.</p>\n<p>You can use all kind of transformers to as a expected values for fields.</p>\n<p>The only difference is for file fields. You cannot check uploaded files just like that, however we prepared a special type of handler\nthat allow to check for some information related to a specific file.</p>\n<p>Let's assume that after upload we display an information with a file name of a uploaded file.</p>\n<p>You can use a special handler that requires to set a element with a postfix <code>Uploaded</code>. This will check if a value of that element is the same as you expected.</p>\n<p>For example you can write a step like this:</p>\n<pre><code class=\"hljs css language-gherkin\">the <span class=\"hljs-string\">\"myform\"</span> form is filled with:\n  |<span class=\"hljs-string\"> myFileUploaded </span>|<span class=\"hljs-string\"> file.txt </span>|\n</code></pre>\n<p>Keep in mind that the element name must end with <code>Uploaded</code> for example:</p>\n<p><code>this.myFileUploaded = $('p.some-file')</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-error-messages-should-be-displayed\"></a><a href=\"#the-error-messages-should-be-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the error messages should be displayed:</code></h2>\n<p>Allows you to specify the error messages that should be displayed for a specific elements.</p>\n<p>This step requires an array of format:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> my error message </span>|\n</code></pre>\n<p>You can use dictionaries in this step as follows:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> d:dictionaryName:dictionaryKey </span>|\n</code></pre>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-navigation\"><span class=\"arrow-prev\">← </span><span>Navigation</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-elements\"><span>Elements</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-fill-the-formname-form-with\"><code>I fill the &quot;:formName&quot; form with:</code></a></li><li><a href=\"#the-formname-form-is-filled-with\"><code>the &quot;:formName&quot; form is filled with:</code></a></li><li><a href=\"#the-error-messages-should-be-displayed\"><code>the error messages should be displayed:</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-forms.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Forms · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to fill forms:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Forms · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to fill forms:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Forms</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-fill-forms\"></a><a href=\"#steps-used-to-fill-forms\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to fill forms:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-fill-the-formname-form-with\"></a><a href=\"#i-fill-the-formname-form-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I fill the &quot;:formName&quot; form with:</code></h2>\n<p>Allows to fill the form with the name <code>:formName</code> and values provided as an array of inputs and values. The element with name <code>:formName</code> must be defined inside the\n<code>currentPage</code> page object.</p>\n<p>Input and values should be provided as an array for example:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> value to be typed into field        </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> value to be typed into textarea     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> radio value to be selected          </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> checkbox label value to be selected </span>|\n</code></pre>\n<p>By default we support all basic HTML field types (text inputs, checkboxes, radios, selects, files and textareas)</p>\n<p>In order to use the default handlers the elements you use as input must follow pattern:</p>\n<p>For inputs:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill</p>\n<p>For textareas:</p>\n<p><code>this.element = $('textarea')</code> - element should point at textarea you want to fill</p>\n<p>For file input:</p>\n<p><code>this.element = $('input')</code> - element should point at input you want to fill and value should a filename of file from <code>data</code> directory</p>\n<p>For selects:</p>\n<p><code>this.element = $('select')</code> - element should point at select and value should be an value of expected option</p>\n<p>For radios:</p>\n<p><code>this.element = $$('radio[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all radio input of given name and value should be an value of radio you wish to select</p>\n<p>For checkboxes:</p>\n<p>Checkbox should have a html like:</p>\n<pre><code class=\"hljs css language-html\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label</span>&gt;</span>\n  My checkbox\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"checkbox\"</span> <span class=\"hljs-attr\">name</span>=<span class=\"hljs-string\">\"some-name\"</span>/&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">label</span>&gt;</span>\n</code></pre>\n<p><code>this.element = $$('checkbox[name=&quot;name-of-radio&quot;]')</code> - element should be an array of all checkboxes of given name and value should be a text from label of checkbox you want to fill</p>\n<p>You can use all kind of transformers to as a values for fields.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-formname-form-is-filled-with\"></a><a href=\"#the-formname-form-is-filled-with\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:formName&quot; form is filled with:</code></h2>\n<p>The same as <code>I fill the &quot;:formName&quot; form with:</code> but allows to check if a form is filled with a given set of values.</p>\n<p>You can use all kind of transformers to as a expected values for fields.</p>\n<p>The only difference is for file fields. You cannot check uploaded files just like that, however we prepared a special type of handler\nthat allow to check for some information related to a specific file.</p>\n<p>Let's assume that after upload we display an information with a file name of a uploaded file.</p>\n<p>You can use a special handler that requires to set a element with a postfix <code>Uploaded</code>. This will check if a value of that element is the same as you expected.</p>\n<p>For example you can write a step like this:</p>\n<pre><code class=\"hljs css language-gherkin\">the <span class=\"hljs-string\">\"myform\"</span> form is filled with:\n  |<span class=\"hljs-string\"> myFileUploaded </span>|<span class=\"hljs-string\"> file.txt </span>|\n</code></pre>\n<p>Keep in mind that the element name must end with <code>Uploaded</code> for example:</p>\n<p><code>this.myFileUploaded = $('p.some-file')</code></p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-error-messages-should-be-displayed\"></a><a href=\"#the-error-messages-should-be-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the error messages should be displayed:</code></h2>\n<p>Allows you to specify the error messages that should be displayed for a specific elements.</p>\n<p>This step requires an array of format:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> my error message </span>|\n</code></pre>\n<p>You can use dictionaries in this step as follows:</p>\n<pre><code class=\"hljs css language-gherkin\">the error messages should be displayed:\n  |<span class=\"hljs-string\"> myElement </span>|<span class=\"hljs-string\"> d:dictionaryName:dictionaryKey </span>|\n</code></pre>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-navigation\"><span class=\"arrow-prev\">← </span><span>Navigation</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-elements\"><span>Elements</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-fill-the-formname-form-with\"><code>I fill the &quot;:formName&quot; form with:</code></a></li><li><a href=\"#the-formname-form-is-filled-with\"><code>the &quot;:formName&quot; form is filled with:</code></a></li><li><a href=\"#the-error-messages-should-be-displayed\"><code>the error messages should be displayed:</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-generators/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Generators · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to generate values:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Generators · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to generate values:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Generators</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-generate-values\"></a><a href=\"#steps-used-to-generate-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to generate values:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-generate-random-generatorparamparam-as-variablename\"></a><a href=\"#i-generate-random-generatorparamparam-as-variablename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></h2>\n<p>Allows to generate a random value using the generator specified by <code>:generator:param:param</code>.</p>\n<p>The generator must be defined inside the any of the <code>generators</code> directories specified in <code>kakunin.conf.js</code> file <code>default: generators</code>.</p>\n<p>If the generator exists, then the value will be saved under the <code>:variableName</code> and can be accessed by:</p>\n<ul>\n<li><p>steps using variable store</p></li>\n<li><p>by calling <code>variableStore.getVariableValue(:variableName)</code></p></li>\n<li><p>by using variable store transformer on supported steps <code>v:variableName</code></p></li>\n</ul>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-files\"><span class=\"arrow-prev\">← </span><span>Files</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-debug\"><span>Debug</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-generate-random-generatorparamparam-as-variablename\"><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-generators.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Generators · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used to generate values:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Generators · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used to generate values:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Generators</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-to-generate-values\"></a><a href=\"#steps-used-to-generate-values\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used to generate values:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-generate-random-generatorparamparam-as-variablename\"></a><a href=\"#i-generate-random-generatorparamparam-as-variablename\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></h2>\n<p>Allows to generate a random value using the generator specified by <code>:generator:param:param</code>.</p>\n<p>The generator must be defined inside the any of the <code>generators</code> directories specified in <code>kakunin.conf.js</code> file <code>default: generators</code>.</p>\n<p>If the generator exists, then the value will be saved under the <code>:variableName</code> and can be accessed by:</p>\n<ul>\n<li><p>steps using variable store</p></li>\n<li><p>by calling <code>variableStore.getVariableValue(:variableName)</code></p></li>\n<li><p>by using variable store transformer on supported steps <code>v:variableName</code></p></li>\n</ul>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/steps-files\"><span class=\"arrow-prev\">← </span><span>Files</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-debug\"><span>Debug</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-generate-random-generatorparamparam-as-variablename\"><code>I generate random &quot;:generator:param:param&quot; as &quot;:variableName&quot;</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-navigation/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Navigation · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used for navigation on page:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Navigation · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used for navigation on page:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Navigation</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-for-navigation-on-page\"></a><a href=\"#steps-used-for-navigation-on-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used for navigation on page:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page\"></a><a href=\"#i-visit-the-pagefilename-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page</code></h2>\n<p>Visits the url of the page object with <code>:pageFileName</code> name.</p>\n<p>In order to make it work we create a page object file with a name of <code>:pageFileName</code>.</p>\n<p>For example in case of: <code>I visit the &quot;myPage&quot; page</code> there should be a file <code>myPage.js</code> inside the <code>pages</code> directory.</p>\n<p>If we have a page object with a name <code>somePageObject.js</code> defined inside <code>pages</code> directory then:</p>\n<p><code>Given I visit the &quot;somePageObject&quot; page</code></p>\n<p>will set <code>this.currentPage</code> variable to <code>somePageObject</code> page and we should end up on <code>somePageObject</code> url.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page-with-parameters\"></a><a href=\"#i-visit-the-pagefilename-page-with-parameters\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></h2>\n<p>The same as <code>I visit the &quot;:pageFileName&quot; page</code> except allows to pass url parameters.</p>\n<p>If url of <code>myPage</code> is defined as <code>this.url = /orders/:orderId/products/:productId</code> then we can use this step to visit this page by:</p>\n<pre><code class=\"hljs css language-gherkin\">I visit the <span class=\"hljs-string\">\"myPage\"</span> page with parameters:\n    |<span class=\"hljs-string\"> orderId   </span>|<span class=\"hljs-string\"> 1 </span>|\n    |<span class=\"hljs-string\"> productId </span>|<span class=\"hljs-string\"> 2 </span>|\n</code></pre>\n<p>this will result in visiting the <code>/orders/1/product/2</code> page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-pagefilename-page-is-displayed\"></a><a href=\"#the-pagefilename-page-is-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:pageFileName&quot; page is displayed</code></h2>\n<p>Checks if current browser url matches url of <code>pageFileName</code> page object.</p>\n<p>If the url matches expected pattern then\n<code>this.currentPage</code> variable is set to <code>pageFileName</code> page object.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/docker\"><span class=\"arrow-prev\">← </span><span>Docker</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-forms\"><span>Forms</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-visit-the-pagefilename-page\"><code>I visit the &quot;:pageFileName&quot; page</code></a></li><li><a href=\"#i-visit-the-pagefilename-page-with-parameters\"><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></a></li><li><a href=\"#the-pagefilename-page-is-displayed\"><code>the &quot;:pageFileName&quot; page is displayed</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/steps-navigation.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Navigation · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"# Steps used for navigation on page:\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Navigation · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"# Steps used for navigation on page:\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Steps</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Navigation</h1></header><article><div><span><h1><a class=\"anchor\" aria-hidden=\"true\" id=\"steps-used-for-navigation-on-page\"></a><a href=\"#steps-used-for-navigation-on-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps used for navigation on page:</h1>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page\"></a><a href=\"#i-visit-the-pagefilename-page\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page</code></h2>\n<p>Visits the url of the page object with <code>:pageFileName</code> name.</p>\n<p>In order to make it work we create a page object file with a name of <code>:pageFileName</code>.</p>\n<p>For example in case of: <code>I visit the &quot;myPage&quot; page</code> there should be a file <code>myPage.js</code> inside the <code>pages</code> directory.</p>\n<p>If we have a page object with a name <code>somePageObject.js</code> defined inside <code>pages</code> directory then:</p>\n<p><code>Given I visit the &quot;somePageObject&quot; page</code></p>\n<p>will set <code>this.currentPage</code> variable to <code>somePageObject</code> page and we should end up on <code>somePageObject</code> url.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"i-visit-the-pagefilename-page-with-parameters\"></a><a href=\"#i-visit-the-pagefilename-page-with-parameters\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></h2>\n<p>The same as <code>I visit the &quot;:pageFileName&quot; page</code> except allows to pass url parameters.</p>\n<p>If url of <code>myPage</code> is defined as <code>this.url = /orders/:orderId/products/:productId</code> then we can use this step to visit this page by:</p>\n<pre><code class=\"hljs css language-gherkin\">I visit the <span class=\"hljs-string\">\"myPage\"</span> page with parameters:\n    |<span class=\"hljs-string\"> orderId   </span>|<span class=\"hljs-string\"> 1 </span>|\n    |<span class=\"hljs-string\"> productId </span>|<span class=\"hljs-string\"> 2 </span>|\n</code></pre>\n<p>this will result in visiting the <code>/orders/1/product/2</code> page.</p>\n<hr>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"the-pagefilename-page-is-displayed\"></a><a href=\"#the-pagefilename-page-is-displayed\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>the &quot;:pageFileName&quot; page is displayed</code></h2>\n<p>Checks if current browser url matches url of <code>pageFileName</code> page object.</p>\n<p>If the url matches expected pattern then\n<code>this.currentPage</code> variable is set to <code>pageFileName</code> page object.</p>\n<hr>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/docker\"><span class=\"arrow-prev\">← </span><span>Docker</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/steps-forms\"><span>Forms</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#i-visit-the-pagefilename-page\"><code>I visit the &quot;:pageFileName&quot; page</code></a></li><li><a href=\"#i-visit-the-pagefilename-page-with-parameters\"><code>I visit the &quot;:pageFileName&quot; page with parameters:</code></a></li><li><a href=\"#the-pagefilename-page-is-displayed\"><code>the &quot;:pageFileName&quot; page is displayed</code></a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/transformers/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Transformers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Transformers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Transformers</h1></header><article><div><span><p>Transformers allow you to transform values passed to form steps.</p>\n<p>For example a select requires to pass a value <code>/options/1b30f17e-e445-4d28-a30c-dedad95829ab</code>. This one is quite unreadable, but with the help of transformers you are\nable to write it like this: <code>d:options:someOptionName</code>.</p>\n<p>In real-life example it will look similar to:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> d:someDictionary:someKey            </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> g:someGenerator                     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> v:someVariableName                  </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> standard value                      </span>|\n</code></pre>\n<p>There are 3 types of built-in transformers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h2>\n<p>Dictionaries allows you to transform a value A to value B using a simple key-&gt;value transformation.</p>\n<p>You can run a dictionary transformer by providing dictionary prefix <code>d:</code>, specifying the dictionary name and key that should be used as a value provider. For example:</p>\n<p><code>d:myDictionaryName:myDictionaryKey</code></p>\n<p>this example assumes that there is a dictionary that supports name <code>myDictionaryName</code> and it has <code>myDictionarKey</code> key.</p>\n<p>You can read about dictionaries in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h2>\n<p>Generators allows you to generate a value by using a specified generator.</p>\n<p>This can be done by: <code>g:generatorName</code>.</p>\n<p>If a generator supports parameters then you can specify them by:</p>\n<p><code>g:generatorName:param1:param2:...:paramN</code></p>\n<p>You can read more about generators in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h2>\n<p>Variable store allows you to fill the form with a value that was saved in previous steps of current running scenario.</p>\n<p>This can be done by:</p>\n<p><code>v:variableName</code></p>\n<p>You can read more about variable store in <code>Extending Kakunin</code> section</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/matchers\"><span class=\"arrow-prev\">← </span><span>Matchers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/extending\"><span>Extending Kakunin</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#variable-store\">Variable store</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/docs/transformers.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Transformers · Kakunin</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta name=\"docsearch:version\" content=\"2.5.0\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Transformers · Kakunin\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Transformers allow you to transform values passed to form steps.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body class=\"sideNavVisible separateOnPageNav\"><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"docsNavContainer\" id=\"docsNav\"><nav class=\"toc\"><div class=\"toggleNav\"><section class=\"navWrapper wrapper\"><div class=\"navBreadcrumb wrapper\"><div class=\"navToggle\" id=\"navToggler\"><div class=\"hamburger-menu\"><div class=\"line1\"></div><div class=\"line2\"></div><div class=\"line3\"></div></div></div><h2><i>›</i><span>Built in mechanisms</span></h2><div class=\"tocToggler\" id=\"tocToggler\"><i class=\"icon-toc\"></i></div></div><div class=\"navGroups\"><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Documentation</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/quickstart\">Quick start</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/\">Getting started</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/configuration\">Configuration</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/how-it-works\">How it works</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Built in mechanisms</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/matchers\">Matchers</a></li><li class=\"navListItem navListItemActive\"><a class=\"navItem\" href=\"/Kakunin/docs/transformers\">Transformers</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/extending\">Extending Kakunin</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Features</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/cross-browser\">Cross-browser testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/parallel-testing\">Parallel testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/performance-testing\">Performance testing</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/docker\">Docker</a></li></ul></div><div class=\"navGroup\"><h3 class=\"navGroupCategoryTitle\">Steps</h3><ul class=\"\"><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-navigation\">Navigation</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-forms\">Forms</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-elements\">Elements</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-files\">Files</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-generators\">Generators</a></li><li class=\"navListItem\"><a class=\"navItem\" href=\"/Kakunin/docs/steps-debug\">Debug</a></li></ul></div></div></section></div><script>\n            var coll = document.getElementsByClassName('collapsible');\n            var checkActiveCategory = true;\n            for (var i = 0; i < coll.length; i++) {\n              var links = coll[i].nextElementSibling.getElementsByTagName('*');\n              if (checkActiveCategory){\n                for (var j = 0; j < links.length; j++) {\n                  if (links[j].classList.contains('navListItemActive')){\n                    coll[i].nextElementSibling.classList.toggle('hide');\n                    coll[i].childNodes[1].classList.toggle('rotate');\n                    checkActiveCategory = false;\n                    break;\n                  }\n                }\n              }\n\n              coll[i].addEventListener('click', function() {\n                var arrow = this.childNodes[1];\n                arrow.classList.toggle('rotate');\n                var content = this.nextElementSibling;\n                content.classList.toggle('hide');\n              });\n            }\n\n            document.addEventListener('DOMContentLoaded', function() {\n              createToggler('#navToggler', '#docsNav', 'docsSliderActive');\n              createToggler('#tocToggler', 'body', 'tocActive');\n\n              var headings = document.querySelector('.toc-headings');\n              headings && headings.addEventListener('click', function(event) {\n                var el = event.target;\n                while(el !== headings){\n                  if (el.tagName === 'A') {\n                    document.body.classList.remove('tocActive');\n                    break;\n                  } else{\n                    el = el.parentNode;\n                  }\n                }\n              }, false);\n\n              function createToggler(togglerSelector, targetSelector, className) {\n                var toggler = document.querySelector(togglerSelector);\n                var target = document.querySelector(targetSelector);\n\n                if (!toggler) {\n                  return;\n                }\n\n                toggler.onclick = function(event) {\n                  event.preventDefault();\n\n                  target.classList.toggle(className);\n                };\n              }\n            });\n        </script></nav></div><div class=\"container mainContainer docsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1 id=\"__docusaurus\" class=\"postHeaderTitle\">Transformers</h1></header><article><div><span><p>Transformers allow you to transform values passed to form steps.</p>\n<p>For example a select requires to pass a value <code>/options/1b30f17e-e445-4d28-a30c-dedad95829ab</code>. This one is quite unreadable, but with the help of transformers you are\nable to write it like this: <code>d:options:someOptionName</code>.</p>\n<p>In real-life example it will look similar to:</p>\n<pre><code class=\"hljs css language-gherkin\">I fill the <span class=\"hljs-string\">\"myForm\"</span> form with:\n  |<span class=\"hljs-string\"> inputElement    </span>|<span class=\"hljs-string\"> d:someDictionary:someKey            </span>|\n  |<span class=\"hljs-string\"> textareaElement </span>|<span class=\"hljs-string\"> g:someGenerator                     </span>|\n  |<span class=\"hljs-string\"> radioElement    </span>|<span class=\"hljs-string\"> v:someVariableName                  </span>|\n  |<span class=\"hljs-string\"> checkboxElement </span>|<span class=\"hljs-string\"> standard value                      </span>|\n</code></pre>\n<p>There are 3 types of built-in transformers:</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"dictionaries\"></a><a href=\"#dictionaries\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Dictionaries</h2>\n<p>Dictionaries allows you to transform a value A to value B using a simple key-&gt;value transformation.</p>\n<p>You can run a dictionary transformer by providing dictionary prefix <code>d:</code>, specifying the dictionary name and key that should be used as a value provider. For example:</p>\n<p><code>d:myDictionaryName:myDictionaryKey</code></p>\n<p>this example assumes that there is a dictionary that supports name <code>myDictionaryName</code> and it has <code>myDictionarKey</code> key.</p>\n<p>You can read about dictionaries in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"generators\"></a><a href=\"#generators\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generators</h2>\n<p>Generators allows you to generate a value by using a specified generator.</p>\n<p>This can be done by: <code>g:generatorName</code>.</p>\n<p>If a generator supports parameters then you can specify them by:</p>\n<p><code>g:generatorName:param1:param2:...:paramN</code></p>\n<p>You can read more about generators in <code>Extending Kakunin</code> section.</p>\n<h2><a class=\"anchor\" aria-hidden=\"true\" id=\"variable-store\"></a><a href=\"#variable-store\" aria-hidden=\"true\" class=\"hash-link\"><svg class=\"hash-link-icon\" aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable store</h2>\n<p>Variable store allows you to fill the form with a value that was saved in previous steps of current running scenario.</p>\n<p>This can be done by:</p>\n<p><code>v:variableName</code></p>\n<p>You can read more about variable store in <code>Extending Kakunin</code> section</p>\n</span></div></article></div><div class=\"docs-prevnext\"><a class=\"docs-prev button\" href=\"/Kakunin/docs/matchers\"><span class=\"arrow-prev\">← </span><span>Matchers</span></a><a class=\"docs-next button\" href=\"/Kakunin/docs/extending\"><span>Extending Kakunin</span><span class=\"arrow-next\"> →</span></a></div></div></div><nav class=\"onPageNav\"><ul class=\"toc-headings\"><li><a href=\"#dictionaries\">Dictionaries</a></li><li><a href=\"#generators\">Generators</a></li><li><a href=\"#variable-store\">Variable store</a></li></ul></nav></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/en/versions/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Kakunin · Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Kakunin · Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"container mainContainer versionsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1>Kakunin Versions</h1></header><h3 id=\"latest\">Current version (Stable)</h3><p>Latest version of Kakunin.</p><table class=\"versions\"><tbody><tr><th>2.5.0</th><td><a href=\"/Kakunin/docs/\">Documentation</a></td><td><a href=\"https://github.com/TheSoftwareHouse/Kakunin/releases/tag/v2.5.0\">Release Notes</a></td></tr></tbody></table><h3 id=\"rc\">Pre-release versions</h3><table class=\"versions\"><tbody><tr><th>next</th><td><a href=\"/Kakunin/docs/next/\">Documentation</a></td></tr></tbody></table><h3 id=\"archive\">Past Versions</h3><table class=\"versions\"><tbody><tr><th>2.4.0</th><td><a href=\"/Kakunin/docs/2.4.0/\">Documentation</a></td><td><a href=\"https://github.com/TheSoftwareHouse/Kakunin/releases/tag/v2.4.0\">Release Notes</a></td></tr></tbody></table><p>You can find past versions of this project on <a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a>.</p></div></div></div></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/en/versions.html",
    "content": "<!DOCTYPE html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Kakunin · Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta name=\"docsearch:language\" content=\"en\"/><meta property=\"og:title\" content=\"Kakunin · Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"container mainContainer versionsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1>Kakunin Versions</h1></header><h3 id=\"latest\">Current version (Stable)</h3><p>Latest version of Kakunin.</p><table class=\"versions\"><tbody><tr><th>2.5.0</th><td><a href=\"/Kakunin/docs/\">Documentation</a></td><td><a href=\"https://github.com/TheSoftwareHouse/Kakunin/releases/tag/v2.5.0\">Release Notes</a></td></tr></tbody></table><h3 id=\"rc\">Pre-release versions</h3><table class=\"versions\"><tbody><tr><th>next</th><td><a href=\"/Kakunin/docs/next/\">Documentation</a></td></tr></tbody></table><h3 id=\"archive\">Past Versions</h3><table class=\"versions\"><tbody><tr><th>2.4.0</th><td><a href=\"/Kakunin/docs/2.4.0/\">Documentation</a></td><td><a href=\"https://github.com/TheSoftwareHouse/Kakunin/releases/tag/v2.4.0\">Release Notes</a></td></tr></tbody></table><p>You can find past versions of this project on <a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a>.</p></div></div></div></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/index.html",
    "content": "<!DOCTYPE HTML>\n<html lang=\"en-US\">\n<head>\n    <meta property=\"og:title\" content=\"Kakunin - E2E testing framework\">\n    <meta property=\"og:description\" content=\"Are you looking for an automation testing tool? Here's Kakunin – an open-source framework for end-to-end, automated software testing.\">\n    <meta property=\"og:type\" content=\"website\">\n    <meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\">\n    <meta http-equiv=\"refresh\" content=\"0; url=docs/index.html\">\n    <script type=\"text/javascript\">\n        window.location.href = 'docs/index.html';\n    </script>\n    <title>Kakunin</title>\n</head>\n<body>\nIf you are not redirected automatically, follow this <a href=\"docs/index.html\">link</a>.\n</body>\n</html>"
  },
  {
    "path": "website/build/Kakunin/js/codetabs.js",
    "content": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n// Turn off ESLint for this file because it's sent down to users as-is.\n\n/* eslint-disable */\nwindow.addEventListener('load', function () {\n  // add event listener for all tab\n  document.querySelectorAll('.nav-link').forEach(function (el) {\n    el.addEventListener('click', function (e) {\n      var groupId = e.target.getAttribute('data-group');\n      document\n        .querySelectorAll('.nav-link[data-group='.concat(groupId, ']'))\n        .forEach(function (el) {\n          el.classList.remove('active');\n        });\n      document\n        .querySelectorAll('.tab-pane[data-group='.concat(groupId, ']'))\n        .forEach(function (el) {\n          el.classList.remove('active');\n        });\n      e.target.classList.add('active');\n      document\n        .querySelector('#'.concat(e.target.getAttribute('data-tab')))\n        .classList.add('active');\n    });\n  });\n});\n"
  },
  {
    "path": "website/build/Kakunin/js/scrollSpy.js",
    "content": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/* eslint-disable */\n(function scrollSpy() {\n  var OFFSET = 10;\n  var timer;\n  var headingsCache;\n\n  var findHeadings = function findHeadings() {\n    return headingsCache || document.querySelectorAll('.toc-headings > li > a');\n  };\n\n  var onScroll = function onScroll() {\n    if (timer) {\n      // throttle\n      return;\n    }\n\n    timer = setTimeout(function () {\n      timer = null;\n      var activeNavFound = false;\n      var headings = findHeadings(); // toc nav anchors\n\n      /**\n       * On every call, try to find header right after  <-- next header\n       * the one whose content is on the current screen <-- highlight this\n       */\n\n      for (var i = 0; i < headings.length; i++) {\n        // headings[i] is current element\n        // if an element is already active, then current element is not active\n        // if no element is already active, then current element is active\n        var currNavActive = !activeNavFound;\n        /**\n         * Enter the following check up only when an active nav header is not yet found\n         * Then, check the bounding rectangle of the next header\n         * The headers that are scrolled passed will have negative bounding rect top\n         * So the first one with positive bounding rect top will be the nearest next header\n         */\n\n        if (currNavActive && i < headings.length - 1) {\n          var heading = headings[i + 1];\n          var next = decodeURIComponent(heading.href.split('#')[1]);\n          var nextHeader = document.getElementById(next);\n\n          if (nextHeader) {\n            var top = nextHeader.getBoundingClientRect().top;\n            currNavActive = top > OFFSET;\n          } else {\n            console.error('Can not find header element', {\n              id: next,\n              heading: heading,\n            });\n          }\n        }\n        /**\n         * Stop searching once a first such header is found,\n         * this makes sure the highlighted header is the most current one\n         */\n\n        if (currNavActive) {\n          activeNavFound = true;\n          headings[i].classList.add('active');\n        } else {\n          headings[i].classList.remove('active');\n        }\n      }\n    }, 100);\n  };\n\n  document.addEventListener('scroll', onScroll);\n  document.addEventListener('resize', onScroll);\n  document.addEventListener('DOMContentLoaded', function () {\n    // Cache the headings once the page has fully loaded.\n    headingsCache = findHeadings();\n    onScroll();\n  });\n})();\n"
  },
  {
    "path": "website/build/Kakunin/sitemap.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:news=\"http://www.google.com/schemas/sitemap-news/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" xmlns:mobile=\"http://www.google.com/schemas/sitemap-mobile/1.0\" xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\" xmlns:video=\"http://www.google.com/schemas/sitemap-video/1.1\"><url><loc>https://thesoftwarehouse.github.io/versions</loc><changefreq>weekly</changefreq><priority>0.5</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/en/versions\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/browserstack</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/browserstack\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/configuration</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/configuration\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/cross-browser</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/cross-browser\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/docker</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/docker\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/extending</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/extending\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/headless</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/headless\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/hooks</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/hooks\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/how-it-works</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/how-it-works\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/matchers</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/matchers\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/parallel-testing</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/parallel-testing\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/performance-testing</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/performance-testing\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/quickstart</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/quickstart\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-debug</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-debug\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-elements</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-elements\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-files</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-files\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-forms</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-forms\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-generators</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-generators\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-navigation</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-navigation\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-rest</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/steps-rest\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/testing-rest-api</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/testing-rest-api\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/next/transformers</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/next/transformers\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/configuration</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/configuration\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/cross-browser</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/cross-browser\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/docker</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/docker\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/extending</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/extending\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/how-it-works</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/how-it-works\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/matchers</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/matchers\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/parallel-testing</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/parallel-testing\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/performance-testing</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/performance-testing\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/quickstart</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/quickstart\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/steps-debug</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/steps-debug\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/steps-elements</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/steps-elements\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/steps-files</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/steps-files\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/steps-forms</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/steps-forms\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/steps-generators</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/steps-generators\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/steps-navigation</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/steps-navigation\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/transformers</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/transformers\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/configuration</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/configuration\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/cross-browser</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/cross-browser\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/docker</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/docker\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/extending</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/extending\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/how-it-works</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/how-it-works\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/matchers</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/matchers\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/parallel-testing</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/parallel-testing\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/performance-testing</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/performance-testing\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/quickstart</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/quickstart\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-debug</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-debug\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-elements</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-elements\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-files</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-files\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-forms</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-forms\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-generators</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-generators\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-navigation</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/steps-navigation\"/></url><url><loc>https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/transformers</loc><changefreq>hourly</changefreq><priority>1.0</priority><xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"https://thesoftwarehouse.github.io/Kakunin/docs/2.4.0/transformers\"/></url></urlset>"
  },
  {
    "path": "website/build/Kakunin/versions/index.html",
    "content": "<!DOCTYPE html><html lang=\"\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Kakunin · Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:title\" content=\"Kakunin · Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"container mainContainer versionsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1>Kakunin Versions</h1></header><h3 id=\"latest\">Current version (Stable)</h3><p>Latest version of Kakunin.</p><table class=\"versions\"><tbody><tr><th>2.5.0</th><td><a href=\"/Kakunin/docs/\">Documentation</a></td><td><a href=\"https://github.com/TheSoftwareHouse/Kakunin/releases/tag/v2.5.0\">Release Notes</a></td></tr></tbody></table><h3 id=\"rc\">Pre-release versions</h3><table class=\"versions\"><tbody><tr><th>next</th><td><a href=\"/Kakunin/docs/next/\">Documentation</a></td></tr></tbody></table><h3 id=\"archive\">Past Versions</h3><table class=\"versions\"><tbody><tr><th>2.4.0</th><td><a href=\"/Kakunin/docs/2.4.0/\">Documentation</a></td><td><a href=\"https://github.com/TheSoftwareHouse/Kakunin/releases/tag/v2.4.0\">Release Notes</a></td></tr></tbody></table><p>You can find past versions of this project on <a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a>.</p></div></div></div></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/build/Kakunin/versions.html",
    "content": "<!DOCTYPE html><html lang=\"\"><head><meta charSet=\"utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/><title>Kakunin · Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/><meta name=\"generator\" content=\"Docusaurus\"/><meta name=\"description\" content=\"Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:title\" content=\"Kakunin · Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:type\" content=\"website\"/><meta property=\"og:url\" content=\"https://thesoftwarehouse.github.io/Kakunin/\"/><meta property=\"og:description\" content=\"Are you looking for an automation testing tool? Here&#x27;s Kakunin – an open-source framework for end-to-end, automated software testing.\"/><meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\"/><meta name=\"twitter:card\" content=\"summary\"/><link rel=\"shortcut icon\" href=\"/Kakunin/img/favicon/favicon.ico\"/><link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css\"/><link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css\"/><script type=\"text/javascript\" src=\"https://buttons.github.io/buttons.js\"></script><script src=\"/Kakunin/js/scrollSpy.js\"></script><link rel=\"stylesheet\" href=\"/Kakunin/css/main.css\"/><script src=\"/Kakunin/js/codetabs.js\"></script></head><body><div class=\"fixedHeaderContainer\"><div class=\"headerWrapper wrapper\"><header><a href=\"/Kakunin/\"><img class=\"logo\" src=\"/Kakunin/img/kakunin_white_logo.svg\" alt=\"Kakunin\"/><h2 class=\"headerTitleWithLogo\">Kakunin</h2></a><a href=\"/Kakunin/versions\"><h3>2.5.0</h3></a><div class=\"navigationWrapper navigationSlider\"><nav class=\"slidingNav\"><ul class=\"nav-site nav-site-internal\"><li class=\"navSearchWrapper reactNavSearchWrapper\"><input type=\"text\" id=\"search_input_react\" placeholder=\"Search\" title=\"Search\"/></li><li class=\"\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\" target=\"_self\">GitHub</a></li></ul></nav></div></header></div></div><div class=\"navPusher\"><div class=\"docMainWrapper wrapper\"><div class=\"container mainContainer versionsContainer\"><div class=\"wrapper\"><div class=\"post\"><header class=\"postHeader\"><h1>Kakunin Versions</h1></header><h3 id=\"latest\">Current version (Stable)</h3><p>Latest version of Kakunin.</p><table class=\"versions\"><tbody><tr><th>2.5.0</th><td><a href=\"/Kakunin/docs/\">Documentation</a></td><td><a href=\"https://github.com/TheSoftwareHouse/Kakunin/releases/tag/v2.5.0\">Release Notes</a></td></tr></tbody></table><h3 id=\"rc\">Pre-release versions</h3><table class=\"versions\"><tbody><tr><th>next</th><td><a href=\"/Kakunin/docs/next/\">Documentation</a></td></tr></tbody></table><h3 id=\"archive\">Past Versions</h3><table class=\"versions\"><tbody><tr><th>2.4.0</th><td><a href=\"/Kakunin/docs/2.4.0/\">Documentation</a></td><td><a href=\"https://github.com/TheSoftwareHouse/Kakunin/releases/tag/v2.4.0\">Release Notes</a></td></tr></tbody></table><p>You can find past versions of this project on <a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a>.</p></div></div></div></div><footer class=\"nav-footer\" id=\"footer\"><section class=\"sitemap\"><a href=\"/Kakunin/\" class=\"nav-home custom\"><img src=\"/Kakunin/img/kakunin_white_logo_text.svg\" alt=\"Kakunin\" width=\"200 \" height=\"77\"/></a><div><h5>Docs:</h5><a href=\"\n                /Kakunin/docs/quickstart\">Quick start</a><a href=\"\n                /Kakunin/docs/configuration\">Configuration</a><a href=\"\n                /Kakunin/docs/extending\">Extending</a></div><div><h5>Features:</h5><a href=\"\n                /Kakunin/docs/cross-browser\">Cross-browser testing</a><a href=\"\n                /Kakunin/docs/parallel-testing\">Parallel testing</a><a href=\"\n                /Kakunin/docs/performance-testing\">Performance testing</a><a href=\"\n                /Kakunin/docs/docker\">Docker</a></div><div><h5>Support:</h5><div class=\"footer-row\"><a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a><a href=\"https://kakunin.io\">Contact us</a></div></div></section><section class=\"copyright\">Copyright © 2021 The Software House</section></footer></div><script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js\"></script><script>\n                document.addEventListener('keyup', function(e) {\n                  if (e.target !== document.body) {\n                    return;\n                  }\n                  // keyCode for '/' (slash)\n                  if (e.keyCode === 191) {\n                    const search = document.getElementById('search_input_react');\n                    search && search.focus();\n                  }\n                });\n              </script><script>\n              var search = docsearch({\n                \n                apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n                indexName: 'kakunin',\n                inputSelector: '#search_input_react',\n                algoliaOptions: {}\n              });\n            </script></body></html>"
  },
  {
    "path": "website/core/Footer.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nconst React = require('react');\n\nclass Footer extends React.Component {\n\n  render() {\n    return (\n      <footer className=\"nav-footer\" id=\"footer\">\n        <section className=\"sitemap\">\n          <a href={this.props.config.baseUrl} className=\"nav-home custom\">\n            {this.props.config.footerIcon && (\n              <img\n                src={this.props.config.baseUrl + this.props.config.footerIcon}\n                alt={this.props.config.title}\n                width=\"200 \"\n                height=\"77\"\n              />\n            )}\n          </a>\n          <div>\n              <h5>Docs:</h5>\n              <a\n                  href={`\n                ${this.props.config.baseUrl}docs/quickstart`}>\n                 Quick start\n              </a>\n              <a\n                  href={`\n                ${this.props.config.baseUrl}docs/configuration`}>\n                  Configuration\n              </a>\n              <a\n                  href={`\n                ${this.props.config.baseUrl}docs/extending`}>\n                  Extending\n              </a>\n          </div>\n            <div>\n                <h5>Features:</h5>\n                <a\n                    href={`\n                ${this.props.config.baseUrl}docs/cross-browser`}>\n                    Cross-browser testing\n                </a>\n                <a\n                    href={`\n                ${this.props.config.baseUrl}docs/parallel-testing`}>\n                    Parallel testing\n                </a>\n                <a\n                    href={`\n                ${this.props.config.baseUrl}docs/performance-testing`}>\n                    Performance testing\n                </a>\n                <a\n                    href={`\n                ${this.props.config.baseUrl}docs/docker`}>\n                    Docker\n                </a>\n            </div>\n          <div>\n\n            <h5>Support:</h5>\n              <div className=\"footer-row\">\n                  <a href=\"https://github.com/TheSoftwareHouse/Kakunin\">GitHub</a>\n                  <a href=\"https://kakunin.io\">Contact us</a>\n              </div>\n          </div>\n        </section>\n\n        <section className=\"copyright\">{this.props.config.copyright}</section>\n      </footer>\n    );\n  }\n}\n\nmodule.exports = Footer;\n"
  },
  {
    "path": "website/package.json",
    "content": "{\n  \"scripts\": {\n    \"examples\": \"docusaurus-examples\",\n    \"start\": \"docusaurus-start\",\n    \"build\": \"docusaurus-build\",\n    \"publish-gh-pages\": \"docusaurus-publish\",\n    \"write-translations\": \"docusaurus-write-translations\",\n    \"version\": \"docusaurus-version\",\n    \"rename-version\": \"docusaurus-rename-version\"\n  },\n  \"devDependencies\": {\n    \"docusaurus\": \"1.14.7\"\n  }\n}\n"
  },
  {
    "path": "website/pages/en/versions.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require('react');\n\nconst CompLibrary = require('../../core/CompLibrary');\n\nconst Container = CompLibrary.Container;\n\nconst CWD = process.cwd();\n\nconst siteConfig = require(`${CWD}/siteConfig.js`);\nconst versions = require(`${CWD}/versions.json`);\n\nfunction Versions() {\n  const latestVersion = versions[0];\n  const repoUrl = `https://github.com/${siteConfig.organizationName}/${\n    siteConfig.projectName\n  }`;\n  return (\n    <div className=\"docMainWrapper wrapper\">\n      <Container className=\"mainContainer versionsContainer\">\n        <div className=\"post\">\n          <header className=\"postHeader\">\n            <h1>{siteConfig.title} Versions</h1>\n          </header>\n          <h3 id=\"latest\">Current version (Stable)</h3>\n            <p>\n                Latest version of Kakunin.\n            </p>\n          <table className=\"versions\">\n            <tbody>\n              <tr>\n                <th>{latestVersion}</th>\n                <td>\n                  <a href={`${siteConfig.baseUrl}docs/`}>Documentation</a>\n                </td>\n                <td>\n                  <a href={`${repoUrl}/releases/tag/v${latestVersion}`}>Release Notes</a>\n                </td>\n              </tr>\n            </tbody>\n          </table>\n          <h3 id=\"rc\">Pre-release versions</h3>\n          <table className=\"versions\">\n            <tbody>\n              <tr>\n                <th>next</th>\n                <td>\n                  <a href={`${siteConfig.baseUrl}docs/next/`}>Documentation</a>\n                </td>\n              </tr>\n            </tbody>\n          </table>\n          <h3 id=\"archive\">Past Versions</h3>\n          <table className=\"versions\">\n            <tbody>\n              {versions.map(\n                version =>\n                  version !== latestVersion && (\n                    <tr>\n                      <th>{version}</th>\n                      <td>\n                        <a href={`${siteConfig.baseUrl}docs/${version}/`}>Documentation</a>\n                      </td>\n                      <td>\n                        <a href={`${repoUrl}/releases/tag/v${version}`}>Release Notes</a>\n                      </td>\n                    </tr>\n                  ),\n              )}\n            </tbody>\n          </table>\n          <p>\n            You can find past versions of this project on{' '}\n            <a href={repoUrl}>GitHub</a>.\n          </p>\n        </div>\n      </Container>\n    </div>\n  );\n}\n\nmodule.exports = Versions;"
  },
  {
    "path": "website/sidebars.json",
    "content": "{\n  \"docs\": {\n    \"Documentation\": [\n      \"quickstart\",\n      \"index\",\n      \"configuration\",\n      \"how-it-works\"\n    ],\n    \"Built in mechanisms\":[\n      \"matchers\",\n      \"transformers\",\n      \"extending\",\n      \"hooks\"\n    ],\n    \"Features\": [\n      \"cross-browser\",\n      \"browserstack\",\n      \"headless\",\n      \"parallel-testing\",\n      \"performance-testing\",\n      \"docker\",\n      \"testing-rest-api\"\n    ],\n    \"Steps\": [\n      \"steps-navigation\",\n      \"steps-forms\",\n      \"steps-elements\",\n      \"steps-files\",\n      \"steps-generators\",\n      \"steps-debug\",\n      \"steps-rest\"\n    ]\n  }\n}\n"
  },
  {
    "path": "website/siteConfig.js",
    "content": "const siteConfig = {\n  title: 'Kakunin',\n  tagline: 'Are you looking for an automation testing tool? Here\\'s Kakunin – an open-source framework for end-to-end, automated software testing.',\n  ogImage: 'img/kakunin_ogImage.jpg',\n  url: 'https://thesoftwarehouse.github.io',\n  baseUrl: '/Kakunin/',\n  projectName: 'Kakunin',\n  organizationName: 'TheSoftwareHouse',\n\n  headerLinks: [\n    {search: true},\n    {href: 'https://github.com/TheSoftwareHouse/Kakunin', label: 'GitHub'},\n  ],\n\n  headerIcon: 'img/kakunin_white_logo.svg',\n  footerIcon: 'img/kakunin_white_logo_text.svg',\n  favicon: 'img/favicon/favicon.ico',\n\n  algolia: {\n    apiKey: '3cda5a3d6672f433f13a4a2cda6d2186',\n    indexName: 'kakunin',\n    algoliaOptions: {} // Optional, if provided by Algolia\n  },\n\n  colors: {\n    primaryColor: '#2F1666',\n    secondaryColor: '#7731F6',\n  },\n\n  copyright: `Copyright © ${new Date().getFullYear()} The Software House`,\n\n  highlight: {\n    theme: 'atom-one-dark',\n  },\n  scripts: ['https://buttons.github.io/buttons.js'],\n  onPageNav: 'separate',\n  cleanUrl: true,\n};\n\nmodule.exports = siteConfig;\n"
  },
  {
    "path": "website/static/css/custom.css",
    "content": "/* your custom css */\n\n@media only screen and (min-device-width: 360px) and (max-device-width: 736px) {\n}\n\n@media only screen and (min-width: 1024px) {\n}\n\n@media only screen and (max-width: 1023px) {\n}\n\n@media only screen and (min-width: 1400px) {\n}\n\n@media only screen and (min-width: 1500px) {\n}\n\n.nav-footer {\n    background-color: #2F1666;\n}\n\n.nav-home.custom {\n    height: auto !important;\n    width: auto !important;\n    padding: 0 10px !important;\n}\n"
  },
  {
    "path": "website/static/index.html",
    "content": "<!DOCTYPE HTML>\n<html lang=\"en-US\">\n<head>\n    <meta property=\"og:title\" content=\"Kakunin - E2E testing framework\">\n    <meta property=\"og:description\" content=\"Are you looking for an automation testing tool? Here's Kakunin – an open-source framework for end-to-end, automated software testing.\">\n    <meta property=\"og:type\" content=\"website\">\n    <meta property=\"og:image\" content=\"https://thesoftwarehouse.github.io/Kakunin/img/kakunin_ogImage.jpg\">\n    <meta http-equiv=\"refresh\" content=\"0; url=docs/index.html\">\n    <script type=\"text/javascript\">\n        window.location.href = 'docs/index.html';\n    </script>\n    <title>Kakunin</title>\n</head>\n<body>\nIf you are not redirected automatically, follow this <a href=\"docs/index.html\">link</a>.\n</body>\n</html>"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/configuration.md",
    "content": "---\nid: version-2.4.0-configuration\ntitle: Configuration\noriginal_id: configuration\n---\n\n## Kakunin config\n\n```\nmodule.exports = {\n    \"browserWidth\": 1600,\n    \"browserHeight\": 900,\n    \"timeout\": 60,\n    \"maxEmailRepeats\": 5,\n    \"intervalEmail\": 5,\n    \"elementsVisibilityTimeout\": 5,\n    \"waitForPageTimeout\": 5,\n    \"downloadTimeout\": 30,\n    \"reports\": \"/reports\",\n    \"downloads\": \"/downloads\",\n    \"data\": \"/data\",\n    \"features\": [\n        \"/features\"\n    ],\n    \"pages\": [\n        \"/pages\"\n    ],\n    \"matchers\": [\n        \"/matchers\"\n    ],\n    \"generators\": [\n        \"/generators\"\n    ],\n    \"form_handlers\": [\n        \"/form_handlers\"\n    ],\n    \"step_definitions\": [\n        \"/step_definitions\"\n    ],\n    \"comparators\": [\n        \"/comparators\"\n    ],\n    \"dictionaries\": [\n        \"/dictionaries\"\n    ],\n    \"transformers\": [\n        \"/transformers\"\n    ],\n    \"regexes\": [\n        \"/regexes\"\n    ],\n    \"hooks\": [\n        \"/hooks\"\n    ],\n    \"clearEmailInboxBeforeTests\": false,\n    \"clearCookiesAfterScenario\": true,\n    \"clearLocalStorageAfterScenario\": true,\n    \"email\": null,\n    \"headless\": false,\n    \"noGpu\": false,\n    \"type\": \"otherWeb\",\n    \"baseUrl\": \"http://localhost:8080\",\n    \"accounts\": {\n        \"someAccount\": {\n            \"accounts\": [\n                {\n                    \"email\": \"\",\n                    \"password\": \"\"\n                }\n            ]\n        }\n    }\n}\n\n```\n\n## Configuration options\n\n`browserWidth` - width of browser window `default: 1600`\n\n`browserheight` - height of browser window `default: 900`\n\n`timeout` - global timeout for a single step execution in seconds `default: 60`\n\n`maxEmailRepeats` - maximum email repeats to catch email used in the email step\n\n`intervalEmail` - interval for email checking step `default: 5` in seconds\n\n`elementsVisibilityTimeout` - maximum wait timeout for element visibility `default: 5` seconds\n\n`waitForPageTimeout` - maximum wait timeout for page visibility `default: 5` seconds\n\n`downloadTimeout` - maximum wait timeout for file to be downloaded `default: 30` seconds\n\n`emails` - array of paths to store emails related custom code\n\n`reports` - path to store reports\n\n`downloads` - path to store downloaded files\n\n`data` - path to store test related files (for example files to be downloaded)\n\n`feature` - array of paths to store features\n\n`pages` - array of paths to store page objects\n\n`matchers` - array of paths to store custom matchers\n\n`generators` - array of paths to store custom generators\n\n`form_handlers` - array of paths to store custom form handlers\n\n`step_definitions` - array of paths to store custom steps\n\n`comparators` - array of paths to store custom comparators\n\n`dictionaries` - array of paths to store custom dictionaries\n\n`transformers` - array of paths to store custom transformers\n\n`regexes` - array of paths to store custom regexes\n\n`hooks` - array of paths to store custom hooks\n\n`clearEmailInboxBeforeTests` - flag to active clearing email inbox before tests are executed `default: false | true for apps with email checking functionality activated `\n\n`clearCookiesAfterScenario` - flag to activate clearing cookies after every scenario `default: true`\n\n`clearLocalStorageAfterScenario` - flag to activate clearing local storage after every scenario `default: true`\n\n`email` - email configuration `default: null`\n\nfor mailtrap email checking system:\n\n```javascript \n\"type\": \"mailtrap\",\n\"config\": {\n    \"apiKey\": \"your-mailtrap-api-key\",\n    \"inboxId\": \"your-mailtrap-inbox\",\n    \"url\": \"https://mailtrap.io/api/v1\"\n}\n```\n\nfor custom email checking system only type is required:\n\n``` \n\"type\": \"custom-type\"\n```\n\n`headless` - flag to activate chrome headless browser `default: false`\n\n`noGpu` - flag to activate cpu only mode `default: false`\n\n`type` - type of application either `ng1 | ng2 | otherWeb`\n\n`baseUrl` - url of tested application\n\n`accounts` - object to store accounts information. This is bound to `userProvider` and allows to use advanced email checking options like recipient checking.\n\n```javascript \n\"someAccount\": {\n    \"accounts\": [\n        {\n            \"email\": \"\",\n            \"password\": \"\"\n        }\n    ]\n}\n```\n\n## Environment variables\n\nKakunin uses a single `.env` file to load ENV variables. By default there is only one:\n\n`FIXTURES_RELOAD_HOST` - allows you to specify host for fixtures reloading. This allows you to use `@reloadFixtures` tag on scenarios that should restore database to starting state, before the test is running\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/cross-browser.md",
    "content": "---\nid: version-2.4.0-cross-browser\ntitle: Cross-browser testing\noriginal_id: cross-browser\n---\n\n## To run tests with specified browser\nThere is a possibility to run Kakunin in various browsers:\n\n- Google Chrome (by default) `npm run kakunin` or `npm run kakunin -- --chrome`\n- Firefox `npm run kakunin -- --firefox`\n- Safari `npm run kakunin -- --safari`\n\n## To run tests in different browsers at once\nThere is a possibility to run more than one instance of WebDriver by giving an extra parameter to a command line:\n\n- `npm run kakunin --chrome --firefox`\n\n\n## Safari\n### Run tests\n1. Open Safari's preferences\n2. Enable \"Show Develop menu in menu bar\"\n3. Open \"Develop\" tab\n4. Enable \"Allow Remote Automation\"\n\n### Troubleshooting\nSafari version 12.0:\n- drag & drop actions in Kakunin impossible (more details https://github.com/angular/protractor/issues/1526)\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/docker.md",
    "content": "---\nid: version-2.4.0-docker\ntitle: Docker\noriginal_id: docker\n---\n\n# Docker for Kakunin tests\n\nThis section explains how to run kakunin tests inside docker, below examples of Dockerfile\nand docker-compose.yml files let you build your first docker image and run tests.\n\n## Dockerfile:\n\nThis file is responsible for building the whole environment for our e2e tests.\nIt will allow you to run tests on local and CI environments, \nby configuring and copying the whole project inside the container.\nJust simply place it inside your e2e project root.\n\nBelow an example of Dockerfile\n\n### Example of Dockerfile:\n```bash\n# Downloading selenium image and setting privileges\nFROM selenium/standalone-chrome:3.14.0\nUSER root\n# Setting test directory\nWORKDIR /app\n# Install openjdk-8-jdk-headless\nRUN apt-get update -qqy \\\n  && apt-get -qqy --no-install-recommends install \\\n    xvfb \\\n    openjdk-8-jdk-headless \\\n    curl \\\n    make \\\n  && rm -rf /var/lib/apt/lists/* /var/cache/apt/*\n# Installing node 8 globally and setting paths\nRUN set -x \\\n    && curl -sL https://deb.nodesource.com/setup_8.x | bash - \\\n    && apt-get install -y \\\n        nodejs \\\n    && npm install -g npm@latest\nRUN PATH=/usr/bin/node:$PATH\n# Copy tests directory with ignored files from .dockerignore\nCOPY --chown=seluser:seluser . .\n# Removing node_modules in case of existence or lack of .dockerignore and installing from package.json\nRUN rm -rf ./node_modules \\\n    && npm install\n# Setting Xvfb\nRUN export DISPLAY=:99.0\nUSER seluser\n```\n\n##docker-compose.yml\n\nCompose is a tool for defining and running multi-container Docker applications, which we use\nfor running our tests.\n\nRunning command: ``docker-compose up -d`` will start Dockerfile script, as a result, it builds the container.\n \nRunning command: ``docker-compose build `` or ``docker-compose up --build`` will \nrebuild container, if there were made any changes.\n \nRunning command: ``docker-compose run --rm e2e`` will start running tests inside the container\n\n\nComposition below allows you to run e2e tests inside the container and configure it locally or\nin CI environments.\n\n\n### Example of docker-compose.yml:\n```bash\ne2e:\n      build: .\n      working_dir: /app\n      command: sh -c \"Xvfb -ac :99 -screen 0 1280x1024x16 & npm run kakunin\"\n```\n\n### How to run step by step\n1. Install docker (e.g Docker for Mac),\n2. Create Dockerfile and docker-compose.yml in the root of your e2e project,\n3. Run in command line `docker-compose up -d ` which will start docker and build image\n if it's not build\n4. Run in command line `docker-compose run --rm e2e` to run your tests\n\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/extending.md",
    "content": "---\nid: version-2.4.0-extending\ntitle: Extending Kakunin\noriginal_id: extending\n---\n\nKakunin allows you to easily add a custom code in order to extend it's functionality.\n\n## Internal services\n\n### Regex builder\n\nRegex builder is a special builder for creating `RegExp` objects based on regexp name. Internally it has access to not only to all built-in \nregular expression files, but also custom ones specified by user. \n\n```javascript\nconst { regexBuilder } = require('kakunin');\n\nconst myRegex = regexBuilder.buildRegex('r:number');\n\n//myRegex will contain RegExp object that matches regular expression under the name \"number\" in regexes file.\n```\n\n### Variable store\n\nVariable store allows you to store and read some values to be used during given scenario.\n\n```javascript\nconst { variableStore } = require('kakunin');\n\nvariableStore.storeVariable('some-name', 'some-value');\n\nconst myValue = variableStore.getVariableValue('some-name'); //contains 'some-value'\n```\n\n### User provider\n\nKakunin comes with functionality that allows you to easily load credentials for a given account type - `UserProvider`.\n\nIn `kakunin.conf.js` you can find a section `accounts`.\n\nThe structure it has is very simple: \n\n```json \n\"accounts\": {\n    \"someAccount\": {\n        \"accounts\": [\n            {\n                \"email\": \"\",\n                \"password\": \"\"\n            }\n        ]\n    }\n}\n```\n\n`someAccount` - the name of accounts group\n\n`accounts` - an array of account credentials (in order to be able to check if a `currentUser` got an email, this has to have an `email` key, otherwise account can have any kind of\nproperties)\n\nUse provider is accessible inside any kind of a step by calling `this.userProvider`. It comes with a single method:\n\n`this.userProvider.getUser(groupName)` - returns an account credentials for a given user group.\n\nIt is a good practice to save a current user in `this.currentUser` variable for a email checking service.\n\n## Adding custom code\n\n### Custom step\n\nIn order to add a custom step, you have to create inside of a directory specified as `step_definitions` in kakunin configuration file `default: /step_definitions`.\n\nWe're using `cucumber-js 4.X` so in order to add custom step you have to use `defineSupportCode` method like this:\n\n```javascript\n  const { defineSupportCode } = require('kakunin');\n  \n  defineSupportCode(({ When }) => {\n    When(/^I use kakunin$/, function() {\n      expect(true).to.equal(true);\n    });\n  });\n```\n\n### Page objects\n\nKakunin comes with some built-in page objects, that should be used as a base for your page objects.\n\nIn order to create a custom one, create a file inside the `pages` directory and extend the `BasePage` from kakunin package.\n\n```javascript\nconst { BasePage } = require('kakunin');\n\nclass MyPageObject extends BasePage {\n  constructor() {\n    this.myElement = element(by.css('.some-elemnt'));\n  }\n}\n\nmodule.exports = MyPageObject;\n```\n\n### Matchers\n\nMatchers are used to compare if given value is matching our expectation. For example if a value in table is a number.\n\nYou can add your own matcher as below:\n\n```javascript\nconst { matchers } = require('kakunin');\n\nclass MyMatcher {\n  isSatisfiedBy(prefix, name) {\n    return prefix === 'm:' && name === 'pending';\n  }\n \n  match(protractorElement, matcherName) {\n    return protractorElement.getText().then((value) => {\n      if (value === 'pending') {\n        return true;\n      }\n      \n      return Promise.reject(`Matcher \"MyMatcher\" could not match value on element \"${protractorElement.locator()}\". Expected: \"pending\", given: \"${value}\"`);\n    }); \n  }\n}\n\nmatchers.addMatcher(new MyMatcher());\n```\n\n### Dictionaries\n\nDictionaries allows you to present complicated values in much more readable way. For example if an element must be\nin a form of IRI `/some-resource/123-123-123-23` and you wish to use `pending-resource` as it's alias.\n\nYou can add your own dictionary:\n\n```javascript\nconst { dictionaries } = require('kakunin');\nconst { BaseDictionary } = require('kakunin');\n\nclass TestDictionary extends BaseDictionary {\n  constructor() {\n    super('name-of-dictionary', {\n      'pending-resource': '/some-resource/123-123-123-23',\n      'test-value': 'some other value'\n    });\n  }\n}\n\ndictionaries.addDictionary(new TestDictionary());\n```\n\n### Generators\n\nGenerators allows you to create random values\n\nYou can add your own generator:\n\n```javascript\nconst { generators } = require('kakunin');\n\nclass MyGeneerator{\n  isSatisfiedBy(name) {\n    return name === 'my-generator';\n  }\n\n  generate(params) {\n    return Promise.resolve('some-random-value');\n  }\n}\n\ngenerators.addGenerator(new MyGeneerator());\n```\n\n### Comparators\n\nComparators allows you to check if a set of values has an expected order\n\nYou can add your own comparators:\n\n```javascript\nconst { comparators } = require('kakunin');\n\nclass MyComparator {\n  isSatisfiedBy(values) {\n    for(let i=0; i<values.length; i++) {\n      if (values[i] !== 'foo' && values[i] !== 'bar') {\n        return false;\n      }\n    }\n\n    return true;\n  }\n  \n  compare(values, order) {\n    for (let i = 1; i < values.length; i++) {\n      const previousValue = values[i - 1];\n      const currentValue = values[i];\n\n      if (previousValue === currentValue) {\n        return Promise.reject('Wrong order');\n      }\n    }\n\n    return Promise.resolve('Foo bar!');\n  }\n};\n\ncomparators.addComparator(new MyComparator());\n```\n\n### Form handlers\n\nForm handlers allows you to fill the form inputs and check value of filled fields\n\nYou can add your own handlers:\n\n```javascript\nconst { handlers } = require('kakunin');\n\nconst MyHandler {\n  constructor() {\n    this.registerFieldType = false;\n    this.fieldType = 'default';\n  }\n\n  isSatisfiedBy(element, elementName) {\n    return Promise.resolve(elementName === 'someElementName');\n  }\n \n  handleFill(page, elementName, desiredValue) {\n    return page[elementName].isDisplayed()\n      .then(function () {\n        return page[elementName].clear().then(function () {\n          return page[elementName].sendKeys(desiredValue);\n        });\n      }\n    );\n  }\n\n  handleCheck(page, elementName, desiredValue) {\n    return page[elementName].isDisplayed()\n      .then(function () {\n        return page[elementName].getAttribute('value').then(function (value) {\n          if (value === desiredValue) {\n            return Promise.resolve();\n          }\n\n          return Promise.reject(`Expected ${desiredValue} got ${value} for text input element ${elementName}`);\n        });\n      }\n    );\n  }\n};\n\nhandlers.addHandler(new MyHandler());\n```\n\n### Transformers\n\nTransformers can be used in steps `When I fill the \"form\" form with:` and `And the \"joinOurStoreForm\" form is filled with:`.\n\nExisting transformers:\n- generators (prefix: `g:`)\n- dictionaries (prefix: `d:`)\n- variableStore (prefix: `v:`)\nTransformers can be used in mentioned steps by using specific 'prefix', parameters are sent after `:` sign.\nExample:\n`g:generatorName:param:param`\n\nYou can add your own handlers:\n```javascript\nconst { transformers } = require('kakunin');\n\nclass MyTransformer {\n\n  isSatisfiedBy(prefix) {\n    return 'yourPrefix:' === prefix;\n  }\n\n  transform(value) {\n    //code\n  }\n}\ntransformers.addTransformer(new MyTransformer());\n```\n\n### Email checking service\n\nYou can easily check emails with Kakunin. By default we give you MailTrap client implementation, but you can easily add your own client. \n\n```javascript\nconst { emailService } = require('kakunin');\n\nclass MyEmailService {\n  //you have access to full kakunin config\n  isSatisfiedBy(config) {\n    return config.email.type === 'my-custom-email-service';\n  }\n  \n  //method used to clear emails before tests\n  clearInbox() {\n    ...\n  }\n  \n  //method used to get emails - this method should return emails in format described below\n  getEmails() {\n    ...\n  }\n  \n  //method used to retrive atachments for given email - should return attachments in format described below\n  getAttachments(email) {\n    ...\n  }\n  \n  //method used to mark given email as read\n  markAsRead(email) {\n    ...\n  }\n}\n\nemailService.addAdapter(new MyEmailService());\n```\n\nEmails should be returned as an array of objects with given schema:\n```javascript \n  [\n    {\n      \"subject\": \"SMTP e-mail test\",\n      \"sent_at\": \"2013-08-25T19:32:07.567+03:00\",\n      \"from_email\": \"me@railsware.com\",\n      \"from_name\": \"Private Person\",\n      \"to_email\": \"test@railsware.com\",\n      \"to_name\": \"A Test User\",\n      \"html_body\": \"\",\n      \"text_body\": \"This is a test e-mail message.\\r\\n\",\n      \"email_size\": 193,\n      \"is_read\": true,\n      \"created_at\": \"2013-08-25T19:32:07.576+03:00\",\n      \"updated_at\": \"2013-08-25T19:32:09.232+03:00\",\n      \"sent_at_timestamp\": 1377448326\n    }\n  ]\n```\n\nthis is MailTrap email format.\n\nAttachments should be returned as an array of objects with given schema:\n\n```javascript\n  [\n    {\n      \"id\": 1737,\n      \"message_id\": 54508,\n      \"filename\": \"Photos.png\",\n      \"attachment_type\": \"attachment\",\n      \"content_type\": \"image/png\",\n      \"content_id\": \"\",\n      \"transfer_encoding\": \"base64\",\n      \"attachment_size\": 213855,\n      \"created_at\": \"2013-08-16T00:39:34.677+03:00\",\n      \"updated_at\": \"2013-08-16T00:39:34.677+03:00\",\n      \"attachment_human_size\": \"210 KB\",\n      \"download_path\": \"/api/v1/inboxes/3/messages/54508/attachments/1737/download\"\n    }\n  ]\n```\n\nthis is MailTrap attachment format.\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/how-it-works.md",
    "content": "---\nid: version-2.4.0-how-it-works\ntitle: How it works\noriginal_id: how-it-works\n---\n\nKakunin is built with `no-js` experience in mind. Because of that you're able to test even complicated apps just\nby knowing Kakunin (Gherkin) steps and a few good practices.\n\n## Concepts\n\nKakunin uses `cucumber-js` internally, because of that all tests (or rather scenarios) are using `Gherkin` as a \"programming\"\nlanguage.\n\nA simple scenario could look like this:\n\n```gherkin\nFeature:\n    Scenario: Display user profile for logged user\n        Given I am logged in as a \"user\"\n        When the \"dashboard\" page is displayed\n        And I click the \"profileButton\" element\n        Then the \"myProfile\" page is displayed\n        And the \"myName\" element is visible\n```\n\nThis is how most of Kakunin test scenarios look like.\n\nThere are a few concepts to be explained.\n\n\n## Page objects\n\nPage object is a code representation of a page displayed in browser. Kakunin has built-in `BasePage` page object, that you should extend.\n\nPage object contains information about page url, its elements, locators, but can also have some custom methods if necessary.\n\nA very simple example of Kakunin's Page Object could look like the following:\n\n```javascript\nconst { BasePage } = require('kakunin');\n\nclass DashboardPage extends BasePage {\n    constructor() {\n        super();\n        \n        this.url = '/dashboard';\n    }\n}\n\nmodule.exports = DashboardPage;\n```\n\nAs you can see a basic Page Object must extend one of the Kakunin's Objects and needs to have url field defined (`this.url`).\n \nThis code should be saved inside `pages` directory in a file with `js` extension. \nNote that a file name is very important, because we're going to use it as parameter for steps. For example, the following step:\n```gherkin\nWhen the \"dashboard\" page is displayed\n``` \nexpects that there is a file named `dashboard.js` inside the `pages` directory. \n\n\nEvery step that we are using is somehow connected to an object called `currentPage`. This object value is set to a \npage object that we expect to be on.\n\nThis is done by two kinds of steps:\n\n* `Then the \"dashboard\" page is displayed` - this one checks if current url in browser is the same as the one inside Page Object and changes a value of the `currentPage` field\n to this page object\n* `When I visit the \"dashboard\" page` - this one goes to the url specified in Page Object and attaches the Page Object to the `currentPage` field as above \n\nThis concept is a very simple and allows you to easily debug the framework. You can be sure that each subsequent step that declared below the ones above will be executed in context of a page object specified in those methods.\nFor example, having the following code:\n\n```gherkin \nFeature:\n    Scenario: Display user profile for logged user\n        Given I am logged in as a \"user\"\n        When the \"dashboard\" page is displayed\n        And I click the \"profileButton\" element\n        Then the \"myProfile\" page is displayed\n        And the \"myName\" element is visible\n```\n\nThe step named `And I click the \"profileButton\" element` is executed in context of `dashboard` Page Object, thus we can assume that `profileButton` should be defined inside the\n`pages/dashboard.js` file.\n\nAt the same time the step `And the \"myName\" element is visible` is executed in context of `myProfile`, so `myName` should be defined in `pages/myProfile.js` file.\n\n\n## Elements and locators\n\nThe second concept that you have to understand are elements and locators.\n\nEvery element that you see on website can be represented as a element inside the page object. This allows us to use it as a parameter for a step, as we did in:\n`And the \"myName\" element is visible`.\n\nDefining elements is very simple. Let's say we have such page object:\n\n``` \nconst { BasePage } = require('kakunin');\n\nclass DashboardPage extends BasePage {\n    constructor() {\n        super();\n        \n        this.url = '/dashboard';\n    }\n}\n\nmodule.exports = DashboardPage;\n```\n\nElements should be defined inside `constructor` method. Let's add element for `myName`:\n\n``` \nconst { BasePage } = require('kakunin');\n\nclass DashboardPage extends BasePage {\n    constructor() {\n        super();\n        \n        this.url = '/dashboard';\n        \n        this.myName = element(by.css('.myName'));\n    }\n}\n\nmodule.exports = DashboardPage;\n```\n\nAs you see we added a single line `this.myName = element(by.css('.myName'));`.\n\n`by.css('.myName')` - is a locator, this is a standard protractor syntax, you can read more on protractors documentation\n\nBy joining `element` method with a locator, we created element to be used by our steps.\n\n\n## Compare URLs examples:\n\n\n  | Page Object URL                                             | Current Browser URL                               | Base URL - config file    | Results   |\n  | ----------------------------------------------------------- | ------------------------------------------------- | ------------------------- | --------- |\n  | http://localhost:8080/incorrect-data                        | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | http://localhost:8080/incorrect-data/                       | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | http://google/incorrect-data                                | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | http://google/tabular-data                                  | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | http://google/incorrect-data/                               | http://localhost:8080/tabular-data                | https://example-url.com   | FALSE     |\n  | /incorrect-data                                             | http://website.com/tabular-data                   | https://example-url.com   | FALSE     |\n  | /incorrect-data/                                            | http://website.com/tabular-data                   | http://incorrect.com      | FALSE     |\n  | http://localhost:8080/tabular-data                          | http://localhost:8080/tabular-data                | https://example-url.com   | TRUE      |\n  | http://localhost:8080/tabular-data/                         | http://localhost:8080/tabular-data                | http://localhost:8080     | TRUE      |\n  | /tabular-data                                               | http://localhost:8080/tabular-data                | http://localhost:8080     | TRUE      |\n  | /tabular-data/                                              | http://localhost:8080/tabular-data                | http://localhost:8080     | TRUE      |\n  | /tabular-data                                               | http://localhost:8080/tabular-data                | https://google.pl         | FALSE     |\n  | /tabular-data/                                              | http://localhost:8080/tabular-data                | https://google.pl         | FALSE     |\n  | /                                                           | https://google.pl/new                             | https://google.pl         | FALSE     |\n  |                                                             | https://google.pl/new                             | https://google.pl         | FALSE     |\n  |                                                             | http://localhost:8080                             | http://localhost:8080     | TRUE      |\n  | /                                                           | https://google.pl                                 | https://google.com        | FALSE     |\n  | https://google.com/:example/:name                           | https://google.com/example/janek                  | https://example-url.com   | TRUE      |\n  | https://google.com/:name                                    | https://google.com/janek                          | https://example-url.com   | TRUE      |\n  | https://google.com/account/:username/settings/display       | https://google.com/account/janek/settings/display | https://example-url.com   | TRUE      |\n  | /account/settings/:userType                                 | https://incorrect-host/account/settings/admin     | https://google.com        | FALSE     |\n  | /account/settings/:userType/something                       | https://incorrect-host/account/settings/admin     | https://example-url.com   | FALSE     |\n  | https://incorrect-host/account/settings/:userType/something | https://incorrect-host/account/settings/admin     | https://example-url.com   | FALSE     |\n  | /account/settings/:userType                                 | https://google.com/account/settings/user          | https://google.com        | TRUE      |\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/index.md",
    "content": "---\nid: version-2.4.0-index\ntitle: Getting started\noriginal_id: index\n---\n\n## About Kakunin\n\nKakunin is a Protractor extension created by The Software House sp. z o.o. and Takamol Holding. It allows you\nto write e2e test scenarios with a help of Gherkin language and JavaScript for all kind of applications - Angular, React and others.\n\n## Installation\n\nIn order to install Kakunin you have to make sure that you have installed:\n\n```text\nnode.js - v7.8.0 min\nJDK\nChrome\n```\n  \nCreate directory for your project\n```bash\nmkdir my_project\n```\n    \nGo to project directory \n```bash\ncd my_project\n```\n    \nInitialize JavaScript project\n```bash\nnpm init\n```\n\nInstall dependencies\n```bash\nnpm install cross-env protractor webdriver-manager kakunin  --save\n```\n    \nInside `package.json` file; add new script in `scripts` section:\n```json\n\"kakunin\": \"cross-env NODE_ENV=prod kakunin\"\n``` \n\n## Configuration\n\n* Create kakunin project\n```bash\nnpm run kakunin init\n```\nThe above command will run Kakunin's init script.\n* Answer what kind of app you're going to test (`default: AngularJS`)\n* Enter URL where your tested app will be running (`default: http://localhost:3000`)\n* Choose if you plan to use some emails checking service (`default: none`)\n\nAlso, there is a possibility to answer these question by a command line.\n```text\nnpm run kakunin init -- --baseUrl https://google.com --type otherWeb --emailType none\n```\nAvailable parameters: `baseUrl`, `type`, `emailType`, `emailApiKey`, `emailInboxId`.\nYou will not be asked about question that you already answered by a command.\n\nAfter the init process, a project files should be automatically created in your directory.\n\nThis is an example of a console output after the init process is completed:\n```text\nCreated file at path /Users/example-user/projects/test/kakunin.conf.js\nCreated directory at path /Users/<user>/TSHProjects/test/reports\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report\nCreated directory at path /Users/<user>/TSHProjects/test/reports/report/features\nCreated directory at path /Users/<user>/TSHProjects/test/reports/performance\nCreated directory at path /Users/<user>/TSHProjects/test/downloads\nCreated directory at path /Users/example-user/projects/test/data\nCreated directory at path /Users/example-user/projects/test/features\nCreated directory at path /Users/example-user/projects/test/pages\nCreated directory at path /Users/example-user/projects/test/matchers\nCreated directory at path /Users/example-user/projects/test/generators\nCreated directory at path /Users/example-user/projects/test/form_handlers\nCreated directory at path /Users/example-user/projects/test/step_definitions\nCreated directory at path /Users/example-user/projects/test/comparators\nCreated directory at path /Users/example-user/projects/test/dictionaries\nCreated directory at path /Users/example-user/projects/test/regexes\nCreated directory at path /Users/example-user/projects/test/hooks\nCreated directory at path /Users/example-user/projects/test/transformers\nCreated directory at path /Users/example-user/projects/test/emails\nCreated file at path /Users/example-user/projects/test/downloads/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/report/features/.gitkeep\nCreated file at path /Users/example-user/projects/test/reports/performance/.gitkeep\nCreated file at path /Users/example-user/projects/test/features/example.feature\nCreated file at path /Users/example-user/projects/test/pages/page.js\nCreated file at path /Users/example-user/projects/test/matchers/matcher.js\nCreated file at path /Users/example-user/projects/test/generators/generator.js\nCreated file at path /Users/example-user/projects/test/step_definitions/steps.js\nCreated file at path /Users/example-user/projects/test/regexes/regex.js\nCreated file at path /Users/example-user/projects/test/hooks/hook.js\n```\n\nAnd you're set! Now you can run the tests using Kakunin:\n\n```bash\nnpm run kakunin\n```\n  \n  \n## Commands\n\n* Create a new project by answering few simple questions (you can pass additional parameter to enter advanced mode where you can configure all Kakunin options by yourself)\n\n    ```bash \n    npm run kakunin init [-- --advanced]\n    ``` \n* Run test scenarios\n\n    ```bash\n    npm run kakunin\n    ```\n* Run only scenarios tagged by `@someTag`\n\n     ```bash\n     npm run kakunin -- --tags @someTag\n     ``` \n* Run only scenarios tagged by `@someTag` and `@otherTag` at the same time\n \n    ```bash\n    npm run kakunin -- --tags \"@someTag and @otherTag\"\n    ```\n \n* Run only scenarios tagged by `@someTag` or `@otherTag`\n     \n     ```bash\n     npm run kakunin -- --tags \"@someTag or @otherTag\"\n     ```\n  \n* Run only scenarios not tagged by `@someTag` \n\n    ```bash\n    npm run kakunin -- --tags \"not @someTag\"\n    ```\n\n## Troubleshooting & Tips\n\nIn order to make cucumber steps autosuggestion work properly in JetBrains tools, make sure your project is `ECMAScript 6` compatible and you have `cucumberjs` plugin installed.\nDue to non-resolved issue in Jetbrains editors ([see here](https://youtrack.jetbrains.com/issue/WEB-11505)) we'll have to do one more step:\n \nGo to `step_definitions` directory \n```bash\ncd step_definitions\n``` \n\nPaste this code into terminal and restart your IDE:\n\nFor Linux/MacOs:\n\n```bash\nln -s ../node_modules/kakunin/dist/step_definitions/elements.js kakunin-elements.js\nln -s ../node_modules/kakunin/dist/step_definitions/debug.js kakunin-debug.js\nln -s ../node_modules/kakunin/dist/step_definitions/file.js kakunin-file.js\nln -s ../node_modules/kakunin/dist/step_definitions/form.js kakunin-form.js\nln -s ../node_modules/kakunin/dist/step_definitions/email.js kakunin-email.js\nln -s ../node_modules/kakunin/dist/step_definitions/generators.js kakunin-generators.js\nln -s ../node_modules/kakunin/dist/step_definitions/navigation.js kakunin-navigation.js \nln -s ../node_modules/kakunin/dist/step_definitions/performance.js kakunin-performance.js \n```\n\nFor Windows 8+: (you have to do this as administrator)\n\n```bash\nmklink kakunin-elements.js ../node_modules/kakunin/dist/step_definitions/elements.js\nmklink kakunin-debug.js ../node_modules/kakunin/dist/step_definitions/debug.js \nmklink kakunin-file.js ../node_modules/kakunin/dist/step_definitions/file.js \nmklink kakunin-form.js ../node_modules/kakunin/dist/step_definitions/form.js \nmklink kakunin-email.js ../node_modules/kakunin/dist/step_definitions/email.js\nmklink kakunin-generators.js ../node_modules/kakunin/dist/step_definitions/generators.js \nmklink kakunin-navigation.js ../node_modules/kakunin/dist/step_definitions/navigation.js \nmklink kakunin-performance.js ../node_modules/kakunin/dist/step_definitions/performance.js \n```\n\nKeep in mind that `mklink` is not available in older Windows distributions.\n\nThis will create symlinks inside `step_definitions` directory and make `cucumberjs` plugin recognize kakunin built-in steps.\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/matchers.md",
    "content": "---\nid: version-2.4.0-matchers\ntitle: Matchers\noriginal_id: matchers\n---\n\nMatchers allows you to check if a element content matches your expectation.\n\nFor example you can check if a value has a specified pattern or if a button is clickable.\n\nUsing matcher is very straightforward, for example: `f:isClickable`.\n\nMatchers can be used in most of the steps related to checking content (with exception of checking form values).\n\nKakunin comes with a set of built in matchers:\n\n## Visibility matcher\n\n`f:isVisible` - checks if element is visible (must be in viewport and cannot be hidden behind any other element)\n\n## Invisibility matcher\n\n`f:isNotVisible` - checks if element is not visible\n\n## Present matcher\n\n`f:isPresent` - checks if element is in html code (does not have to be visible)\n\n## Clickable matcher\n\n`f:isClickable` - checks if element is clickable\n\n## Not clickable matcher\n\n`f:isNotClickable` - checks if element is not clickable\n\n## Attribute matcher\n\n`attribute:attributeName:regexName` - allows to check if element has attribute with a name specified by `attributeName` and it has to \nhave a format passing `regexName`\n\nFor example, if there is an element:\n\n`<p custom-attribute=\"123123\">some value</p>`\n\nyou can check if attribute is an number by running: `attribute:custom-attribute:number`\n\n## Regex matcher\n\n`r:regexName` - allows you to run a `regexName` against a text value of element\n\nRegexes have to be specified inside `regex` directory or be a kakunin built ones:\n\n`notEmpty` - there must be a value\n`number` - must be a number\n\nYou can add your own matchers. In order to do so please read `Extending Kakunin` section.\n\n## Text matcher\n\n`t:text you are looking for` - allows you to check if an element contains a expected text\n\n## Current date matcher\n\n`f:currentDate:{format}` - allows you to generate current date, `{format}` is optional, by default `DD-MM-YYYY`"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/parallel-testing.md",
    "content": "---\nid: version-2.4.0-parallel-testing\ntitle: Parallel testing\noriginal_id: parallel-testing\n---\nThere is a possibility to run tests in parallel.\n\n## How to execute\nUse a command `npm run kakunin -- --parallel <number of instances>` where `number of instances` is a number.\n\nExample:\n- `npm run kakunin -- --chrome --parallel 2`\n\n<span style=\"color:red\">Keep in mind that the merged report is available in the `reports/report/index.html` file. text</span>\n\n## Specify pattern per each instance\n- `npm run kakunin -- --parallel <number of instances> --pattern <regex to much feature> --pattern <regex to much feature>`\n\nKeep in mind that:\n\n- the number given in `parallel` must be equal to passed `patterns`\n- `<number of instances>` is a number of instances of the specified browser\n- `<regex>` is a pattern that is used to specify the list of specs that will be executed in each of the instances\n-----------------------------------------------------------------------------------\n\n## Troubleshooting\n1. Running more than one instance in `Firefox` is not possible now (fix in-progress).\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/performance-testing.md",
    "content": "---\nid: version-2.4.0-performance-testing\ntitle: Performance testing\noriginal_id: performance-testing\n---\n\nPerformance testing is possible thanks to `browsermob-proxy`.\n\nIt saves all data from network tab (Google Chrome console) which is generated during the test.\n\nThere is a possibility to compare `TTFB` value with a maximum given one. \n\n`TTFB` (Time to first byte) measures the duration from the client making an HTTP request to the first byte of a response being received by the client's browser.\n\nMore details can be found in documentation - `Built-in steps` section.\n\n# What needs to be done?\n\n## Get started\n\n1. Download `browsermob-proxy` from `https://github.com/lightbody/browsermob-proxy`\n\n2. Navigate in terminal to the catalog\n\n3. Use following command to start the REST API\n\n```\n./browsermob-proxy -port 8887\n```\n\n## Configuration\n1. Add `browsermob-proxy` configuration to `kakunin.conf.js`\n\nYou can use one of the following methods to configure browsermob-proxy:\n\n- `npm run kakunin init -- --advanced` and go through the process\n\n- or add it manually to the config file:\n\n```javascript\n    \"browserMob\": {\n      \"serverPort\": 8887,\n      \"port\": 8888,\n      \"host\": \"localhost\"\n    }\n```\n\n## Run tests\n\n1. `performance steps` must be used in the scenario where you are testing performance\n\n2. Scenario must have a tag `@performance`\n\n3. Run tests with special parameter:\n\n```\nnpm run kakunin -- --performance\n```\n\n## Results\n\n1. `.har` files are saved in catalog `reports/performance/*.har`\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/quickstart.md",
    "content": "---\nid: version-2.4.0-quickstart\ntitle: Quick start\noriginal_id: quickstart\n---\nAs a quick demonstration of the framework let's test the \n[React variant of TodoMVC](http://todomvc.com/examples/react/#/) project. \nOf course other testing other frameworks is possible, you can try it \nby yourself!\n\n## Install packages\nIn order to install Kakunin you have to make sure that you have installed:\n\n```text\nnode.js - v7.8.0 min\nJDK\nChrome\n```\n  \nCreate directory for your project and enter it\n\n```bash\n$mkdir my_project\ncd my_project\n```\n    \nInitialize JavaScript project\n```bash\nnpm init\n```\n\nInstall dependencies\n\n```bash\nnpm install cross-env protractor webdriver-manager kakunin  --save\n```\n\nInside `package.json` file add new script in `scripts` section:\n```js\n...\n\"scripts\": {\n  \"kakunin\": \"cross-env NODE_ENV=prod kakunin\"\n},\n...\n```\n\n## Configure Kakunin\nRun initialization command \n\n```bash\nnpm run kakunin init\n```\n\nAnswer literally few questions:\n\n```text\nWhat kind of application would you like to test? : otherWeb\n        \nWhat is base url? [http://localhost:3000]: http://todomvc.com\n           \nWhat kind of email service would you like to use?: none\n```  \nAnd you're set! Now let's write some test!\n\n## Test the app\n\nCreate a page object that will contain instructions on how to locate elements in the projects.\nCreate a file `pages/main.js`:\n\n```javascript\nconst { BasePage } = require('kakunin');\n\nclass MainPage extends BasePage {\n    constructor() {\n        super();\n\n        // define the main url for the page\n        this.url = '/examples/react/#/';\n\n        // whole form tag\n        this.addTodoForm = $('.todoapp');\n\n        // input field\n        this.todoInput = $('input.new-todo');\n\n        // list of currently added todos\n        this.todos = $$('.todo-list .view');\n        this.todoLabel = by.css('label');\n\n        // first todo item in a list\n        this.firstTodoItem = this.todos.get(0);\n    }\n}\n\nmodule.exports = MainPage;\n```\n\nNow that we have prepared the locators, we can start writing our test. Let's test adding new todo item. \n\nCreate a file named: `features/adding_todo.feature` with the following contents:\n\n```gherkin\nFeature:\n\n    Scenario: Adding todo\n        Given I visit the \"main\" page\n        And I wait for \"visibilityOf\" of the \"addTodoForm\" element\n        And the \"addTodoForm\" element is visible\n        When I fill the \"addTodoForm\" form with:\n            | todoInput | My new todo |\n        And I press the \"enter\" key\n        Then there are \"equal 1\" \"todos\" elements\n\n```\n\nAnd that's it! All you have to do now is to run the test and watch the magic happens ;)\n\n```bash\nnpm run kakunin\n```\n\nThe tests may run quite fast so you might not been able to see that it \nreally works as expected. To check if the todo items has been really \nadded to the list, let's use a simple hack - let's pause the running \ntest right after the todo has been added. \n\nTo do that, let's upgrade our Scenario. Update the file:\n```gherkin\nFeature:\n\n    Scenario: Adding todo\n        Given I visit the \"main\" page\n        And I wait for \"visibilityOf\" of the \"addTodoForm\" element\n        And the \"addTodoForm\" element is visible\n        When I fill the \"addTodoForm\" form with:\n            | todoInput | My new todo |\n        And I wait for \"1\" seconds\n        And I press the \"enter\" key\n        When I fill the \"addTodoForm\" form with:\n            | todoInput | Another todo item! |\n        And I wait for \"1\" seconds\n        And I press the \"enter\" key\n        Then there are \"equal 2\" \"todos\" elements\n        Then I wait for \"5\" seconds\n\n``` \n\nAs you can see, we've added 1 new step that waits for a second before \n\"pressing\" the `enter` key. We've also added a second todo item with \na short pause at the end of the test so you can see the changes.\n\nIf you want to see what can we do more with the TodoMVC project, take a look \nat the `example` dir, where you'll find a complete set of test for the project.\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/steps-debug.md",
    "content": "---\nid: version-2.4.0-steps-debug\ntitle: Debug\noriginal_id: steps-debug\n---\n\n# Steps for debugging application:\n\n## `I pause`\n\nPauses tests execution and allows to continue manually by pressing combination of `ctrl+c` inside terminal.\n\n---\n\n## `I wait for \":seconds\" seconds`\n\nWaits with execution of next step for an amount provided by parameter `:seconds`.\n\n---\n\n## `I start performance monitor mode`\n\nIt starts performance monitor mode.\n\nKeep in mind that REST API must be started on the port which must configured in `kakunin.conf.js` - `serverPort: 8887`.\n\nMore details can be found in documentation file `performance-testing.md`.\n\n---\n\n## `I save performance report file as \"fileName\"`\n\nIt saves `.har` file with a name `fileName` in `reports/performance` catalog.\n\nFor example: `exampleReport-1511470954552.har`\n\nData is generated during the test - network tab in Chrome Chrome console.\n\nKeep in mind:\n\n* `I start performance monitor mode` must be used before this step\n\n* `browserMob.port` must be configured in `kakunin.conf.js`\n\n* `browserMob.host` must be configured in `kakunin.conf.js`\n\nMore details can be found in documentation file `performance-testing.md`.\n\n---\n\n## `the requests should take a maximum of \"maxTiming\" milliseconds`\n\nIt compares every `TTFB` timing value from previously saved `.har` report with a `maxTiming` value.\n\nSlow requests are listed in your terminal in red colour.\n\nKeep in mind that `I start performance monitor mode` and `I save performance report file as \"fileName\"` steps must be executed before this one!\n\n---\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/steps-elements.md",
    "content": "---\nid: version-2.4.0-steps-elements\ntitle: Elements\noriginal_id: steps-elements\n---\n\n# Steps used to interact with elements:\n## `I infinitely scroll to the \":elementName\" element`\n\nAllows to scroll through infinite scroll mechanism.\n\nThe `:elementName` is a name of a selector for loading trigger.\n\n---\n\n## `I wait for \":expectedConditionName\" of the \":elementName\" element`\n\nWaits till element `:elementName` from `this.currentPage` meets criteria specified by `:expectedConditionName`.\n\nYou can use any of the Protractor's expected condition:\n\n* `visibilityOf`\n* `invisibilityOf`\n\netc.\n\nRead more in Protractor's API documentation.\n\n---\n\n## `I wait for the \":elementName\" element to disappear`\n\nWaits till element `:elementName` disappears.\n\n---\n\n## `I scroll to the \":elementName\" element`\n\nScrolls to element `:elementName` of `this.currentPage`. The element will be on bottom of the page.\n\n---\n\n## `I infinitely scroll to the \":elementName\" element`\n\nAllows to scroll till `:elementName` is visible. Useful for infinite scrolling functionality.\n\n---\n\n## `I press the \":keyName\" key`\n\nPerforms a key press operation on `:keyName` key.\n\n---\n\n## `I click the \":elementName\" element`\n\nPerforms a click action on element `:elementName` from `this.currentPage'\n\nThe child element must be specified by `:elementName` and must be available in `this.currentPage`.\n\n---\n\n## `I store the \":elementName\" element text as \":variableName\" variable`\n\nStores the text from element `:elementName` of `this.currentPage` under the `:variableName` so you can use it later.\n\n---\n\n## `I update the \":elementName\" element text as \":variableName\" variable`\n\nUpdates the variable `:variableName` value by value from element `:elementName` of `this.currentPage`.\n\n---\n\n## `I store the \":elementName\" element text matched by \":matchingRegex\" as \":variableName\" variable`\n\nStores the part of the element `:elementName` text, that matches the `:matchingRegex` under the `:variableName` for later use.\n\n---\n## `the \":elementName\"\" element is visible`\n\nChecks if element `:elementName` is visible and clickable\n\n---\n\n## `the \":elementName\"\" element is not visible`\n\nChecks if element `:elementName` is available in HTML DOM but is not visible and clickable\n\n---\n\n## `the \":elementName\" element is disabled`\n\nChecks if element is disabled\n\n---\n\n## `I store table \":tableRow\" rows as \":variableName\" with columns:`\n\nAllows to store a row specified columns from a table `:tableRow` and save it under `:variableName` as an array of objects.\n\nThis step requires a table of columns elements, for example:\n\n```gherkin\nI store table \"someRow\" rows as \"someVariable\" with columns:\n  | firstName |\n  | lastName  |\n  | id        |\n```\n\nIn order to make it work there must be not only array element `this.someRow = $$('.rows')` in `this.currentPage`, but also\nelement `this.firstName = $('.firstName');` and so on.\n\nThe result of this step is an array of:\n\n```javascript\n[\n  [\n    'firsRowFirstNameValue',\n    'firsRowLastNameValue'\n    'firsRowIdValue'\n  ]\n  ...\n]\n```\n\n---\n\n## `there are following elements in table \":elementName\":`\n\nAllows to check if a child elements of `:elementName` have a specified content.\n\nThis steps allows you to specify an array of child elements that will be checked against expected values.\n\nFor example:\n\n```gherkin\nthere are following elements in table \"myTable\":\n  | id  | firstName | lastName |\n  | t:1 | t:Adam    | t:Doe    |\n  | t:2 | t:John    | t:Doe    |\n```\n\nFirst row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.\n\nThis step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.\n\nWe can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).\n\n---\n\n## `there are \"numberExpression\" following elements for element \":elementName\":`\n\nAllows to check if a child elements of `:elementName` have a specified content. Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nAllows to check if a number of elements is the one that we expect.\n\n`numberExpression` is a supported expression from `chai.js` library:\n\n* `equal N` where N is a number\n\n* `at least N` where N is a number\n\n* `above N` where N is a number\n\n* `below N` where N is a number\n\n* `within N M` where N and M are a numbers\n\nand so on. You can check expressions on `chai.js` API dock for BDD.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthere are \"equal 5\" following elements for element \"myList\":\n  | viewButton | f:isClickable |\n  | id         | r:idRegex     |\n```\n\nThe child elements must be an elements, for example `this.viewButton = $('button.viewButton');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `there is element \":elementName\" with value \":matcher\"`\n\nAllows to check if `:elementName` has a value that matches the `:matcher`.\n\n---\n\n## `there is no element \":elementName\" with value \":matcherName\"`\n\nAllows to check if there is no `:elementName` that matches the `:matcher`.\n\n---\n\n## `there are \"numberExpression\" \":elementName\" elements`\n\nAllows to check if a number of `:elementName` elements is the same as we expect.\n\n`numberExpression` is a supported expression from `chai.js` library:\n\n* `equal N` where N is a number\n\n* `at least N` where N is a number\n\n* `above N` where N is a number\n\n* `below N` where N is a number\n\n* `within N M` where N and M are a numbers\n\nand so on. You can check expressions on `chai.js` API dock for BDD.\n\n`:elementName` should be specified as an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\n---\n\n## `every \":elementName\" element should have the same value for element \":columnElementName\"`\n\nAllows to check if every row defined by `:elementName` has the same value for a column `:columnElementName`.\n\n`:elementName` must be an array of elements\n\n`:columnElementName` must be an element, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>1</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')` and we can specify column element\n`this.myColumn = $('td');`. This allows us to write:\n\n`every \"myElement\" element should have the same value for element \"myColumn\"`\n\n---\n\n## `the element \":elementName\" should have an item with values:`\n\nAllows to check if any of the child elements of `:elementName` have a specified content (one matching element is enough). Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthe element \"myList\" should have an item with values:\n  | id | t:1 |\n```\n\nThe child elements must be an elements, for example `this.id = $('td');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `the element \":elementName\" should not have an item with values:`\n\nAllows to check if the child elements of `:elementName` have a different content than that given in the table. Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthe element \"myList\" should have an item with values:\n  | id | t:does-not-exist |\n```\n\nThe child elements must be an elements, for example `this.id = $('td');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `I drag \":elementDrag\" element and drop over \":elementDrop\" element`\n\nClicks on `:elementDrag` and moves it onto `:elementDrop` while left mouse button is pressed, and then release it.\n\nNote: This step is not working on HTML5!\n\n---\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/steps-files.md",
    "content": "---\nid: version-2.4.0-steps-files\ntitle: Files\noriginal_id: steps-files\n---\n\n\n# Steps used to interact with files:\n## `the file \":fileName\" should be downloaded`\n\nChecks if a file with name `:fileName` was downloaded.\n\nThis step does not support matchers or regular expressions, so the name must be exact match. However you can use\nvariable store here.\n\nLet's assume there is a variable `myFile` with a value `super-file` in variable store.\n\nYou can write `the file \"v:myFile.zip\" should be downloaded` to check if a file `super-file.zip` was downloaded.\n\n---\n\n## `the file \":fileName\" contains table data stored under \":variableName\" variable`\n\nThis step allows you to compare an xls/xlsx file `:fileName` with an existing data stored under `:variableName` variable.\n\nThe data under `:variableName` must be an array of objects representing each row of file.\n\n---\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/steps-forms.md",
    "content": "---\nid: version-2.4.0-steps-forms\ntitle: Forms\noriginal_id: steps-forms\n---\n\n# Steps used to fill forms:\n\n## `I fill the \":formName\" form with:`\n\nAllows to fill the form with the name `:formName` and values provided as an array of inputs and values. The element with name `:formName` must be defined inside the\n`currentPage` page object.\n\nInput and values should be provided as an array for example:\n\n```gherkin\nI fill the \"myForm\" form with:\n  | inputElement    | value to be typed into field        |\n  | textareaElement | value to be typed into textarea     |\n  | radioElement    | radio value to be selected          |\n  | checkboxElement | checkbox label value to be selected |\n```\n\nBy default we support all basic HTML field types (text inputs, checkboxes, radios, selects, files and textareas)\n\nIn order to use the default handlers the elements you use as input must follow pattern:\n\nFor inputs:\n\n`this.element = $('input')` - element should point at input you want to fill\n\nFor textareas:\n\n`this.element = $('textarea')` - element should point at textarea you want to fill\n\nFor file input:\n\n`this.element = $('input')` - element should point at input you want to fill and value should a filename of file from `data` directory\n\nFor selects:\n\n`this.element = $('select')` - element should point at select and value should be an value of expected option\n\nFor radios:\n\n`this.element = $$('radio[name=\"name-of-radio\"]')` - element should be an array of all radio input of given name and value should be an value of radio you wish to select\n\nFor checkboxes:\n\nCheckbox should have a html like:\n\n```html\n<label>\n  My checkbox\n  <input type=\"checkbox\" name=\"some-name\"/>\n</label>\n```\n\n`this.element = $$('checkbox[name=\"name-of-radio\"]')` - element should be an array of all checkboxes of given name and value should be a text from label of checkbox you want to fill\n\nYou can use all kind of transformers to as a values for fields.\n\n---\n\n## `the \":formName\" form is filled with:`\n\nThe same as `I fill the \":formName\" form with:` but allows to check if a form is filled with a given set of values.\n\nYou can use all kind of transformers to as a expected values for fields.\n\nThe only difference is for file fields. You cannot check uploaded files just like that, however we prepared a special type of handler\nthat allow to check for some information related to a specific file.\n\nLet's assume that after upload we display an information with a file name of a uploaded file.\n\nYou can use a special handler that requires to set a element with a postfix `Uploaded`. This will check if a value of that element is the same as you expected.\n\nFor example you can write a step like this:\n\n```gherkin\nthe \"myform\" form is filled with:\n  | myFileUploaded | file.txt |\n```\n\nKeep in mind that the element name must end with `Uploaded` for example:\n\n`this.myFileUploaded = $('p.some-file')`\n\n---\n\n## `the error messages should be displayed:`\n\nAllows you to specify the error messages that should be displayed for a specific elements.\n\nThis step requires an array of format:\n\n```gherkin\nthe error messages should be displayed:\n  | myElement | my error message |\n```\n\nYou can use dictionaries in this step as follows:\n\n```gherkin\nthe error messages should be displayed:\n  | myElement | d:dictionaryName:dictionaryKey |\n```\n\n---\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/steps-generators.md",
    "content": "---\nid: version-2.4.0-steps-generators\ntitle: Generators\noriginal_id: steps-generators\n---\n\n# Steps used to generate values:\n\n## `I generate random \":generator:param:param\" as \":variableName\"`\n \n\nAllows to generate a random value using the generator specified by `:generator:param:param`.\n\nThe generator must be defined inside the any of the `generators` directories specified in `kakunin.conf.js` file `default: generators`.\n\nIf the generator exists, then the value will be saved under the `:variableName` and can be accessed by:\n\n* steps using variable store\n\n* by calling `variableStore.getVariableValue(:variableName)`\n\n* by using variable store transformer on supported steps `v:variableName`\n\n---\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/steps-navigation.md",
    "content": "---\nid: version-2.4.0-steps-navigation\ntitle: Navigation\noriginal_id: steps-navigation\n---\n\n# Steps used for navigation on page:\n\n## `I visit the \":pageFileName\" page`\n\nVisits the url of the page object with `:pageFileName` name.\n\nIn order to make it work we create a page object file with a name of `:pageFileName`.\n\nFor example in case of: `I visit the \"myPage\" page` there should be a file `myPage.js` inside the `pages` directory.\n\nIf we have a page object with a name `somePageObject.js` defined inside `pages` directory then:\n\n`Given I visit the \"somePageObject\" page`\n\nwill set `this.currentPage` variable to `somePageObject` page and we should end up on `somePageObject` url.\n\n---\n\n## `I visit the \":pageFileName\" page with parameters:`\n\nThe same as `I visit the \":pageFileName\" page` except allows to pass url parameters.\n\nIf url of `myPage` is defined as `this.url = /orders/:orderId/products/:productId` then we can use this step to visit this page by:\n\n```gherkin\nI visit the \"myPage\" page with parameters:\n    | orderId   | 1 |\n    | productId | 2 |\n```\n\nthis will result in visiting the `/orders/1/product/2` page.\n\n---\n\n## `the \":pageFileName\" page is displayed`\n\nChecks if current browser url matches url of `pageFileName` page object.\n\nIf the url matches expected pattern then\n`this.currentPage` variable is set to `pageFileName` page object.\n\n---\n"
  },
  {
    "path": "website/versioned_docs/version-2.4.0/transformers.md",
    "content": "---\nid: version-2.4.0-transformers\ntitle: Transformers\noriginal_id: transformers\n---\n\nTransformers allow you to transform values passed to form steps.\n\nFor example a select requires to pass a value `/options/1b30f17e-e445-4d28-a30c-dedad95829ab`. This one is quite unreadable, but with the help of transformers you are\nable to write it like this: `d:options:someOptionName`.\n\nIn real-life example it will look similar to:\n\n```gherkin \nI fill the \"myForm\" form with:\n  | inputElement    | d:someDictionary:someKey            |\n  | textareaElement | g:someGenerator                     |\n  | radioElement    | v:someVariableName                  |\n  | checkboxElement | standard value                      |\n```\n\nThere are 3 types of built-in transformers:\n\n## Dictionaries\n\nDictionaries allows you to transform a value A to value B using a simple key->value transformation.\n\nYou can run a dictionary transformer by providing dictionary prefix `d:`, specifying the dictionary name and key that should be used as a value provider. For example:\n\n`d:myDictionaryName:myDictionaryKey`\n\nthis example assumes that there is a dictionary that supports name `myDictionaryName` and it has `myDictionarKey` key.\n\nYou can read about dictionaries in `Extending Kakunin` section.\n\n## Generators\n\nGenerators allows you to generate a value by using a specified generator.\n\nThis can be done by: `g:generatorName`.\n\nIf a generator supports parameters then you can specify them by:\n\n`g:generatorName:param1:param2:...:paramN`\n\nYou can read more about generators in `Extending Kakunin` section.\n\n## Variable store\n\nVariable store allows you to fill the form with a value that was saved in previous steps of current running scenario.\n\nThis can be done by:\n\n`v:variableName`\n\nYou can read more about variable store in `Extending Kakunin` section\n"
  },
  {
    "path": "website/versioned_docs/version-2.5.0/steps-elements.md",
    "content": "---\nid: version-2.5.0-steps-elements\ntitle: Elements\noriginal_id: steps-elements\n---\n\n# Steps used to interact with elements:\n## `I infinitely scroll to the \":elementName\" element`\n\nAllows to scroll through infinite scroll mechanism.\n\nThe `:elementName` is a name of a selector for loading trigger.\n\n---\n\n## `I wait for \":expectedConditionName\" of the \":elementName\" element`\n\nWaits till element `:elementName` from `this.currentPage` meets criteria specified by `:expectedConditionName`.\n\nYou can use any of the Protractor's expected condition:\n\n* `visibilityOf`\n* `invisibilityOf`\n\netc.\n\nRead more in Protractor's API documentation.\n\n---\n\n## `I wait for the \":elementName\" element to disappear`\n\nWaits till element `:elementName` disappears.\n\n---\n\n## `I scroll to the \":elementName\" element`\n\nScrolls to element `:elementName` of `this.currentPage`. The element will be on bottom of the page.\n\n---\n\n## `I infinitely scroll to the \":elementName\" element`\n\nAllows to scroll till `:elementName` is visible. Useful for infinite scrolling functionality.\n\n---\n\n## `I press the \":keyName\" key`\n\nPerforms a key press operation on `:keyName` key.\n\n---\n\n## `I click the \":elementName\" element`\n\nPerforms a click action on element `:elementName` from `this.currentPage'\n\nThe child element must be specified by `:elementName` and must be available in `this.currentPage`.\n\n---\n\n## `I store the \":elementName\" element text as \":variableName\" variable`\n\nStores the text from element `:elementName` of `this.currentPage` under the `:variableName` so you can use it later.\n\n---\n\n## `I update the \":elementName\" element text as \":variableName\" variable`\n\nUpdates the variable `:variableName` value by value from element `:elementName` of `this.currentPage`.\n\n---\n\n## `I store the \":elementName\" element text matched by \":matchingRegex\" as \":variableName\" variable`\n\nStores the part of the element `:elementName` text, that matches the `:matchingRegex` under the `:variableName` for later use.\n\n---\n## `the \":elementName\"\" element is visible`\n\nChecks if element `:elementName` is visible and clickable\n\n---\n\n## `the \":elementName\"\" element is not visible`\n\nChecks if element `:elementName` is available in HTML DOM but is not visible and clickable\n\n---\n\n## `the \":elementName\" element is disabled`\n\nChecks if element is disabled\n\n---\n\n## `I store table \":tableRow\" rows as \":variableName\" with columns:`\n\nAllows to store a row specified columns from a table `:tableRow` and save it under `:variableName` as an array of objects.\n\nThis step requires a table of columns elements, for example:\n\n```gherkin\nI store table \"someRow\" rows as \"someVariable\" with columns:\n  | firstName |\n  | lastName  |\n  | id        |\n```\n\nIn order to make it work there must be not only array element `this.someRow = $$('.rows')` in `this.currentPage`, but also\nelement `this.firstName = $('.firstName');` and so on.\n\nThe result of this step is an array of:\n\n```javascript\n[\n  [\n    'firsRowFirstNameValue',\n    'firsRowLastNameValue'\n    'firsRowIdValue'\n  ]\n  ...\n]\n```\n\n---\n\n## `there are following elements in table \":elementName\":`\n\nAllows to check if a child elements of `:elementName` have a specified content.\n\nThis steps allows you to specify an array of child elements that will be checked against expected values.\n\nFor example:\n\n```gherkin\nthere are following elements in table \"myTable\":\n  | id  | firstName | lastName |\n  | t:1 | t:Adam    | t:Doe    |\n  | t:2 | t:John    | t:Doe    |\n```\n\nFirst row must specify columns elements. Starting from second row we must provide a matchers for each row that must be displayed.\n\nThis step checks exact match, so if the table has 5 rows, there must be a 5 rows in this table.\n\nWe can specify only a set of columns (for example if a table has 5 columns, we can specify only 1).\n\n---\n\n## `there are \"numberExpression\" following elements for element \":elementName\":`\n\nAllows to check if a child elements of `:elementName` have a specified content. Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nAllows to check if a number of elements is the one that we expect.\n\n`numberExpression` is a supported expression from `chai.js` library:\n\n* `equal N` where N is a number\n\n* `at least N` where N is a number\n\n* `above N` where N is a number\n\n* `below N` where N is a number\n\n* `within N M` where N and M are a numbers\n\nand so on. You can check expressions on `chai.js` API dock for BDD.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthere are \"equal 5\" following elements for element \"myList\":\n  | viewButton | f:isClickable |\n  | id         | r:idRegex     |\n```\n\nThe child elements must be an elements, for example `this.viewButton = $('button.viewButton');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `there is element \":elementName\" with value \":matcher\"`\n\nAllows to check if `:elementName` has a value that matches the `:matcher`.\n\n---\n\n## `there is element \":elementName\" containing \":matcher\" text`\n\nAllows to check if `:elementName` contains a text that matches the `:matcher`.\n\n---\n\n## `there is element \":elementName\" matching \":matcher\" matcher`\n\nAllows to check if `:elementName` matches the given type of `:matcher`. For example:\n\n```gherkin\nthere is element \"button\" matching \"isClickable\" matcher\n```\n\n---\n\n## `there is element \":elementName\" with regex \":matcher\"`\n\nAllows to check if `:elementName` matches given type of regex. For example:\n\n```gherkin\nthere is element \"input\" with regex \"notEmpty\"\n```\n\n---\n\n## `there is no element \":elementName\" with value \":matcherName\"`\n\nAllows to check if there is no `:elementName` that matches the `:matcher`.\n\n---\n\n## `there is no element \":elementName\" containing \":matcher\" text`\n\nAllows to check if `:elementName` doesn't contain a text that matches the `:matcher`.\n\n---\n\n## `there is no element \":elementName\" matching \":matcher\" matcher`\n\nAllows to check if `:elementName` is not matching the given type of `:matcher`.\n\n---\n\n## `there is no element \":elementName\" with regex \":matcher\"`\nAllows to check if `:elementName` is not matching given type of regex.\n\n---\n\n## `there are \"numberExpression\" \":elementName\" elements`\n\nAllows to check if a number of `:elementName` elements is the same as we expect.\n\n`numberExpression` is a supported expression from `chai.js` library:\n\n* `equal N` where N is a number\n\n* `at least N` where N is a number\n\n* `above N` where N is a number\n\n* `below N` where N is a number\n\n* `within N M` where N and M are a numbers\n\nand so on. You can check expressions on `chai.js` API dock for BDD.\n\n`:elementName` should be specified as an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\n---\n\n## `every \":elementName\" element should have the same value for element \":columnElementName\"`\n\nAllows to check if every row defined by `:elementName` has the same value for a column `:columnElementName`.\n\n`:elementName` must be an array of elements\n\n`:columnElementName` must be an element, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>1</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')` and we can specify column element\n`this.myColumn = $('td');`. This allows us to write:\n\n`every \"myElement\" element should have the same value for element \"myColumn\"`\n\n---\n\n## `the element \":elementName\" should have an item with values:`\n\nAllows to check if any of the child elements of `:elementName` have a specified content (one matching element is enough). Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthe element \"myList\" should have an item with values:\n  | id | t:1 |\n```\n\nThe child elements must be an elements, for example `this.id = $('td');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `the element \":elementName\" should not have an item with values:`\n\nAllows to check if the child elements of `:elementName` have a different content than that given in the table. Element should be an array, for example:\n\n```html\n<table>\n  <tr>\n    <td>1</td>\n  </tr>\n  <tr>\n    <td>2</td>\n  </tr>\n</table>\n```\n\nfor this case the `:elementName` should be specified as `$$('table tr')`.\n\nThis step requires an array of elements to be checked. For example:\n\n```gherkin\nthe element \"myList\" should have an item with values:\n  | id | t:does-not-exist |\n```\n\nThe child elements must be an elements, for example `this.id = $('td');`.\n\nYou can use all kind of matchers here.\n\n---\n\n## `I drag \":elementDrag\" element and drop over \":elementDrop\" element`\n\nClicks on `:elementDrag` and moves it onto `:elementDrop` while left mouse button is pressed, and then release it.\n\nNote: This step is not working on HTML5!\n\n---\n"
  },
  {
    "path": "website/versioned_sidebars/version-2.4.0-sidebars.json",
    "content": "{\n  \"version-2.4.0-docs\": {\n    \"Documentation\": [\n      \"version-2.4.0-quickstart\",\n      \"version-2.4.0-index\",\n      \"version-2.4.0-configuration\",\n      \"version-2.4.0-how-it-works\"\n    ],\n    \"Built in mechanisms\": [\n      \"version-2.4.0-matchers\",\n      \"version-2.4.0-transformers\",\n      \"version-2.4.0-extending\"\n    ],\n    \"Features\": [\n      \"version-2.4.0-cross-browser\",\n      \"version-2.4.0-parallel-testing\",\n      \"version-2.4.0-performance-testing\",\n      \"version-2.4.0-docker\"\n    ],\n    \"Steps\": [\n      \"version-2.4.0-steps-navigation\",\n      \"version-2.4.0-steps-forms\",\n      \"version-2.4.0-steps-elements\",\n      \"version-2.4.0-steps-files\",\n      \"version-2.4.0-steps-generators\",\n      \"version-2.4.0-steps-debug\"\n    ]\n  }\n}\n"
  },
  {
    "path": "website/versions.json",
    "content": "[\n  \"2.5.0\",\n  \"2.4.0\"\n]\n"
  }
]